管理主AEM機

部署無AEM頭應用程式需要注AEM意如何構建URL,以確保使用正AEM確的主機/域。 要注意的主URL/請求類型有:

通常,無AEM頭應用會與GraphQL API和映AEM像請求的單個服務交互。 服AEM務根據無頭應用AEM部署更改:

無AEM頭部署類型 AEM環境 AEM服務
生產 生產 發佈
創作預覽 生產 預覽
開發 開發 發佈

要處理部署類型排列,每個應用程式部署都使用指定要連接的AEM服務的配置來構建。 然後,AEM使用配置服務的主機/域來構造AEMGraphQL API URL和映像URL。 要確定管理構建相關配置的正確方法,請參考AEMHeadless應用的框架(例如,React、iOS、Android™等)文檔,因為方法因框架而異。

客戶端類型 單頁應用(SPA) Web元件/JS 行動 伺服器到伺服器
AEM主機配置

以下是構建URL的可能方法示例 AEMGraphQL API影像請求,適用於幾種流行的無頭框架和平台。

AEMGraphQL API請求

必須將從無頭應用到AEMGraphQL API的HTTPGET請求配置為與正確的服務AEM交互,如

使用時 無AEM頭SDK (適用於基於瀏覽器的JavaScript、基於伺服器的JavaScript和Java™),AEM主機可以使用服務初始化AEMHeadless客戶端對AEM像以進行連接。

開發自定義AEMHeadless客戶端時,確AEM保服務的主機可基於生成參數進行參數化。

範例

以下是GraphQL API請AEM求如何使主機值AEM可針對各種無頭應用框架進行配置的示例。

 反應示例

此示例基於 無AEM頭反應應用,說明如AEM何配置GraphQL API請求以根據環境變AEM量連接到不同服務。

應用應使用 用AEM於JavaScript的無頭客戶端 與GraphQL APIAEM交互。 Headless AEMClient for JavaScript提AEM供的Headless客戶端必須使用其連接的AEM服務主機初始化。

反應環境檔案

反應用 自定義環境檔案.env 檔案,儲存在項目的根中以定義生成特定的值。 例如, .env.development 檔案包含開發期間使用的值,而 .env.production 包含用於生產生成的值。

  • .env.development
# Environment variable used to specify the AEM service the React app will connect to when running under this profile
REACT_APP_AEM_HOST=https://publish-p123-e456.adobeaemcloud.com
...

.env 用於其他用途的檔案 可以指定 後裝 .env 和語義描述符,如 .env.stage.env.production。 不同 .env 運行或構建React應用時,可通過設定 REACT_APP_ENV 執行前 npm 的子菜單。

例如, React應用 package.json 可能包含以下內容 scripts 配置:

  • package.json
...
"scripts": {
  "build:development": "REACT_APP_ENV=development npm run build",
  "build:stage": "REACT_APP_ENV=stage npm run build",
  "build:production": "REACT_APP_ENV=production npm run build"
},
...

無AEM頭客戶

用AEM於JavaScript的無頭客戶端 包AEM含向GraphQL API發出HTTP請求AEM的無頭客戶端。 Headless客AEM戶端必須使用與其交AEM互的主機初始化,使用活動 .env 的子菜單。

  • src/api/headlessClient.js
const { AEMHeadless } = require('@adobe/aem-headless-client-js');
...
// Get the environment variables for configuring the headless client,
// specifically the `REACT_APP_AEM_HOST` which contains the AEM service host.
const {
    REACT_APP_AEM_HOST,         // https://publish-p123-e456.adobeaemcloud.com
    REACT_APP_GRAPHQL_ENDPOINT,
} = process.env;
...

// Initialize the AEM Headless client with the AEM Service host, which dictates the AEM service provides the GraphQL data.
export const aemHeadlessClient = new AEMHeadless({
    serviceURL: REACT_APP_AEM_HOST,
    endpoint: REACT_APP_GRAPHQL_ENDPOINT
});

反應useEffect(…) 鈎

自定義React useEffect掛接代表呈AEM現視圖的React元件調用與主AEM機初始化的Headless客戶端。

  • src/api/persistedQueries.js
import { aemHeadlessClient , mapErrors} from "./headlessClient";
...
// The exported useEffect hook
export const getAdventureByPath = async function(adventurePath) {
    const queryVariables = {'adventurePath': adventurePath};
    return executePersistedQuery('wknd-shared/adventures-by-path', queryVariables);
}
...
// Private function that invokes the aemHeadlessClient
const executePersistedQuery = async function(persistedQueryPath, queryVariables) {
    let data;
    let errors;

    try {
        // Run the persisted query using using the aemHeadlessClient that's initialized with the AEM host
        const response = await aemHeadlessClient.runPersistedQuery(persistedQueryPath, queryVariables);
        // The GraphQL data is stored on the response's data field
        data = response.data;
        errors = response.errors ? mapErrors(response.errors) : undefined;
    } catch (e) {
        console.error(e.toJSON());
        errors = e;
    }

    return {data, errors};
}

反應組分

自定義useEffect掛接, useAdventureByPath 導入,用於使用AEMHeadless客戶端獲取資料,並最終向最終用戶呈現內容。

  • 'src/components/AdventureDetail.js'
import { useAdventureByPath } from './api/persistedQueries';
...
// Query AEM GraphQL APIs via the useEffect hook that invokes the AEM Headless client initialized with the AEM host
let { data, error } = useAdventureByPath('/content/dam/wknd-shared/en/adventures/bali-surf-camp/adobestock-175749320.jpg')

...
 iOS™示例

此示例基於 示例AEM無頭iOS™應用,說明如AEM何配置GraphQL API請求以根據 特定於生成的配置變數

iOS™應用需要自AEM定義無頭客戶端與AEMGraphQL API交互。 必AEM須編寫無頭客戶端,以便AEM可配置服務主機。

生成配置

XCode配置檔案包含預設配置詳細資訊。

  • Config.xcconfig
// The http/https protocol scheme used to access the AEM_HOST
AEM_SCHEME = https

// Target hostname for AEM service, do not include the scheme: http:// or https://
AEM_HOST = publish-p123-e789.adobeaemcloud.com
...

初始化自定義無AEM頭客戶端

示例無AEM頭iOS應用 使用使用AEM的配置值初始化的自定義無頭客戶端 AEM_SCHEMEAEM_HOST

...
let aemScheme: String = try Configuration.value(for: "AEM_SCHEME")  // https
let aemHost: String = try Configuration.value(for: "AEM_HOST")      // publish-p123-e456.adobeaemcloud.com

let aemHeadlessClient = Aem(scheme: aemScheme, host: aemHost);

自定義無AEM頭客戶端(api/Aem.swift)包含方法 makeRequest(..) 為AEMGraphQL API請求加上已配置AEM schemehost

  • api/Aem.swift
/// #makeRequest(..)
/// Generic method for constructing and executing AEM GraphQL persisted queries
private func makeRequest(persistedQueryName: String, params: [String: String] = [:]) -> URLRequest {
    // Encode optional parameters as required by AEM
    let persistedQueryParams = params.map { (param) -> String in
        encode(string: ";\(param.key)=\(param.value)")
    }.joined(separator: "")

    // Construct the AEM GraphQL persisted query URL, including optional query params
    let url: String = "\(self.scheme)://\(self.host)/graphql/execute.json/" + persistedQueryName + persistedQueryParams;

    var request = URLRequest(url: URL(string: url)!);

    return request;
}

可以建立新的生成配置檔案 連接到不同AEM的服務。 的特定於生成的值 AEM_SCHEMEAEM_HOST 基於XCode中的選定內部版本使用,導致定制AEM的Headless客戶端與正確的服務AEM連接。

 Android™示例

此示例基於 示例AEM無頭Android™應用,說明如AEM何配置GraphQL API請求,以基於特定於生成(或風格)的AEM配置變數連接到不同的服務。

Android™應用程式(當用Java™編寫時)應使用 用AEM於Java™的無頭客戶端 與GraphQL APIAEM交互。 Headless AEM Client for Java™提AEM供的Headless客戶端必須使用其連接的AEM服務主機初始化。

生成配置檔案

Android™應用定義「productFlavors」,用於生成不同用途的工件。
此示例說明如何定義兩種Android™產品風格,提供不同AEM的服務主機(AEM_HOST)開發值(dev)和生產(prod)使用。

在應用中 build.gradle 檔案,新 flavorDimension 命名 env 的子菜單。

env 維,二 productFlavors 定義: devprod。 每個 productFlavor 使用 buildConfigField 設定定義要連接的服務AEM的生成特定變數。

  • app/build.gradle
android {
    ...
    flavorDimensions 'env'
    productFlavors {
        dev {
            dimension 'env'
            applicationIdSuffix '.dev'
            buildConfigField "String", "AEM_HOST", '"http://10.0.2.2:4503"'
            ...
        }
        prod {
            dimension 'env'
            buildConfigField "String", "AEM_HOST", '"https://publish-p123-e789.adobeaemcloud.com"'
            ...
        }
    }
    ...
}

Android™載入器

初始化 AEMHeadlessClient 生成器,由AEMHeadless Client for Java™提供, AEM_HOSTbuildConfigField 的子菜單。

  • app/src/main/java/com/adobe/wknd/androidapp/loader/AdventuresLoader.java
public class AdventuresLoader extends AsyncTaskLoader<AdventureList> {
    ...

    @Override
    public AdventureList loadInBackground() {
        ...
        // Initialize the AEM Headless client using the AEM Host exposed via BuildConfig.AEM_HOST
        AEMHeadlessClientBuilder builder = AEMHeadlessClient.builder().endpoint(BuildConfig.AEM_HOST);
        AEMHeadlessClient client = builder.build();
        // With the AEM headless client initialized, make GraphQL persisted query calls to AEM
        ...
    }
    ...
}

為不同用途構建Android™應用時,請指定 env 並使用相應AEM的主機值。

圖AEM像URL

必須將來自無頭應用的映AEM像請求配置為與正確的AEM服務交互,如 上表

而AEMGraphQL ... on ImageRef 提供欄位 _authorUrl_publishUrl 包含各個服務的AEM絕對URL,通常使用 _path 欄位,並為用AEM於查詢GraphQL API的服務AEM主機添加前置詞。

使用 _path 如果無頭應用可以基於部署上下文連接到AEM作者或AEM發佈,則會特別有用。

如果無頭應用只與AEM作者或發佈交互, _authorUrl_publishUrl 可以使用欄位來簡化實現,並可以忽略下例中的指導。

範例

以下是影像URL如何為可針對各種無頭AEM應用框架配置的主機值加前置詞的示例。 這些示例假定使用GraphQL查詢,這些查詢使用 _path 的子菜單。

例如:

GraphQL永續查詢

此GraphQL查詢返回影像引用的 _path。 如 GraphQL響應 不包括主機。

query ($path: String!) {
  adventureByPath(_path: $path) {
    item {
      title,
      primaryImage {
        ... on ImageRef {
          _path
        }
      }
    }
  }
}

GraphQL響應

此GraphQL響應返回映像引用的 _path 不包括主機。

{
  "data": {
    "adventureByPath": {
      "item": {
        "adventurePrimaryImage": {
          "_path": "/content/dam/wknd-shared/en/adventures/bali-surf-camp/adobestock-175749320.jpg",
        }
      }
    }
  }
}
 反應示例

此示例基於 示例無AEM頭React應用,說明如何根據環境變數將映像URL配置AEM為連接到正確的服務。

此示例說明如何為影像引用添加前置詞 _path 欄位,可配置 REACT_APP_AEM_HOST 反應環境變數。

反應環境檔案

反應用 自定義環境檔案.env 檔案,儲存在項目的根中以定義生成特定的值。 例如, .env.development 檔案包含開發期間使用的值,而 .env.production 包含用於生產生成的值。

  • .env.development
# Environment variable used to specify the AEM service the React app will connect to when running under this profile
REACT_APP_AEM_HOST=https://publish-p123-e456.adobeaemcloud.com
...

.env 用於其他用途的檔案 可以指定 後裝 .env 和語義描述符,如 .env.stage.env.production。 不同 .env 運行或生成React應用時,可通過設定 REACT_APP_ENV 執行前 npm 的子菜單。

例如, React應用 package.json 可能包含以下內容 scripts 配置:

  • package.json
...
"scripts": {
  "build:development": "REACT_APP_ENV=development npm run build",
  "build:stage": "REACT_APP_ENV=stage npm run build",
  "build:production": "REACT_APP_ENV=production npm run build"
},
...

反應組分

「反應」(React)元件導入 REACT_APP_AEM_HOST 環境變數,並為映像添加前置詞 _path 值,以提供完全可解析的影像URL。

同樣 REACT_APP_AEM_HOST 環境變數用於初始化AEM由 useAdventureByPath(..) 自定義useEffect掛接,用於從中獲取GraphQL數AEM據。 使用與影像URL相同的變數構造GraphQL API請求,確保React應用與兩個使用案例的同AEM一服務交互。

  • 'src/components/AdventureDetail.js'
...
// Import the AEM origin from the app's environment configuration
const AEM_HOST = env.process.REACT_APP_AEM_HOST; // https://publish-p123-e456.adobeaemcloud.com

let { data, error } = useAdventureByPath('/content/dam/wknd-shared/en/adventures/bali-surf-camp/adobestock-175749320.jpg')

return (
    // Prefix the image src URL with the AEM host
    <img src={AEM_HOST + data.adventureByPath.item.primaryImage._path }>
    {/* Resulting in: <img src="https://publish-p123-e456.adobeaemcloud.com/content/dam/wknd-shared/en/adventures/bali-surf-camp/adobestock-175749320.jpg"/>  */}
)
 iOS™示例

此示例基於 示例AEM無頭iOS™應用,說明AEM如何將映像URL配置為根據 特定於生成的配置變數

生成配置

XCode配置檔案包含預設配置詳細資訊。

  • Config.xcconfig
// The http/https protocol scheme used to access the AEM_HOST
AEM_SCHEME = https

// Target hostname for AEM service, do not include the scheme: http:// or https://
AEM_HOST = publish-p123-e789.adobeaemcloud.com
...

影像URL生成器

Aem.swift,自定義無AEM頭客戶端實現,自定義函式 imageUrl(..) 採用中提供的影像路徑 _path GraphLQ響應中的欄位,並將其與主機AEM預先。 然後,每當呈現影像時,在iOS視圖中調用此函式。

  • WKNDAdventures/AEM/Aem.swift
class Aem: ObservableObject {
    let scheme: String
    let host: String
    ...
    init(scheme: String, host: String) {
        self.scheme = scheme
        self.host = host
    }
    ...
    /// Prefixes AEM image paths wit the AEM scheme/host
    func imageUrl(path: String) -> URL {
        return URL(string: "\(self.scheme)://\(self.host)\(path)")!
    }
    ...
}

iOS觀

iOS視圖和前置詞影像 _path 值,以提供完全可解析的影像URL。

  • WKNDAdventures/Views/AdventureListItemView.swift
import SDWebImageSwiftUI
...
struct AdventureListItemView: View {
    @EnvironmentObject private var aem: Aem

    var adventure: Adventure

    var body: some View {
        HStack {
            // Path the image path to `aem.imageUrl(..)` to prepend the AEM service host
            AdventureRowImage(imageUrl: aem.imageUrl(path: adventure.image()))
            Text(adventure.title)
            Spacer()
        }
    }
}
...

可以建立新的生成配置檔案 連接到不同AEM的服務。 的特定於生成的值 AEM_SCHEMEAEM_HOST 基於XCode中的選定內部版本使用,導致定制AEMHeadless客戶端與正確的服務AEM交互。

 Android™示例

此示例基於 示例AEM無頭Android™應用,說明了AEM如何根據生成特定(或類型)配置變AEM量將映像URL配置為連接到不同的服務。

生成配置檔案

Android™應用定義「productFlavors」,用於生成不同用途的工件。
此示例說明如何定義兩種Android™產品風格,提供不同AEM的服務主機(AEM_HOST)開發值(dev)和生產(prod)使用。

在應用中 build.gradle 檔案,新 flavorDimension 命名 env 的子菜單。

env 維,二 productFlavors 定義: devprod。 每個 productFlavor 使用 buildConfigField 設定定義要連接的服務AEM的生成特定變數。

  • app/build.gradle
android {
    ...
    flavorDimensions 'env'
    productFlavors {
        dev {
            dimension 'env'
            applicationIdSuffix '.dev'
            buildConfigField "String", "AEM_HOST", '"http://10.0.2.2:4503"'
            ...
        }
        prod {
            dimension 'env'
            buildConfigField "String", "AEM_HOST", '"https://publish-p123-e789.adobeaemcloud.com"'
            ...
        }
    }
    ...
}

載入圖AEM像

Android™使用 ImageGetter 從中獲取並本地快取映像數AEM據。 在 prepareDrawableFor(..) 在活動AEM生成配置中定義的服務主機用於為建立可解析URL的映像路徑添加前置詞AEM。

  • app/src/main/java/com/adobe/wknd/androidapp/loader/RemoteImagesCache.java
...
public class RemoteImagesCache implements Html.ImageGetter {
    ...
    private final Map<String, Drawable> drawablesByPath = new HashMap<>();
    ...
    public void prepareDrawableFor(String path) {
        ...

        // Prefix the image path with the build config AEM_HOST variable
        String urlStr = BuildConfig.AEM_HOST + path;

        URL url = new URL(urlStr);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // Get the image data from AEM
        Drawable drawable = Drawable.createFromStream(is, new File(path).getName());
        ...
        // Save the image data into the cache using the path as the key
        drawablesByPath.put(path, drawable);
        ...
    }

    @Override
    public Drawable getDrawable(String path) {
        // Get the image data from the cache using the path as the key
        Drawable drawable = drawablesByPath.get(path);
        return drawable;
    }
}

Android™視圖

Android™視圖通過 RemoteImagesCache 使用 _path 值。

  • app/src/main/java/com/adobe/wknd/androidapp/AdventureDetailFragment.java
...
public class AdventureDetailFragment extends Fragment implements LoaderManager.LoaderCallbacks<Adventure> {
    ...
    private ImageView adventureDetailImage;
    ...

    private void updateContent() {
        ...
        adventureDetailImage.setImageDrawable(RemoteImagesCache.getInstance().getDrawable(adventure.getPrimaryImagePath()));
        ...
    }
...
}

為不同用途構建Android™應用時,請指定 env 並使用相應AEM的主機值。

本頁內容