Een React-app ontwikkelen die AEM GraphQL API's gebruikt

In dit hoofdstuk verkent u hoe AEM GraphQL API's de ervaring in een externe toepassing kunnen aansturen.

Een eenvoudige React app wordt gebruikt om Team en Persoon inhoud te vragen en te tonen die door GraphQL APIs wordt blootgesteld te AEM. Het gebruik van React is grotendeels onbelangrijk, en de verbruikende externe toepassing zou in om het even welk kader voor om het even welk platform kunnen worden geschreven.

Vereisten

Men veronderstelt dat de stappen die in de vorige delen van dit meerdelige leerprogramma worden geschetst zijn voltooid, of basis-tutorial-solution.content.zipis geïnstalleerd op uw Auteur van AEM as a Cloud Service en de diensten van Publish.

winde screenshots in dit hoofdstuk komen uit Code van Visual Studio

De volgende software moet worden geïnstalleerd:

Doelstellingen

Leer hoe u:

  • De voorbeeldtoepassing React downloaden en starten
  • De vraag AEM GraphQL eindpunten gebruikend AEM Zwaarloze JS SDK
  • De AEM van de vraag voor een lijst van teams, en hun referenced leden
  • De AEM van de vraag voor de details van een teamlid

De voorbeeldtoepassing React ophalen

In dit hoofdstuk wordt een uitgelijnde voorbeeldtoepassing React geïmplementeerd met de code die vereist is voor interactie met AEM GraphQL API en de gegevens van het weergaveteam en de persoon die van hen zijn verkregen.

De voorbeeldbroncode van de React-app is beschikbaar op Github.com op https://github.com/adobe/aem-guides-wknd-graphql/tree/main/basic-tutorial

Zo krijgt u de React-app:

  1. Kloon de steekproefWKND GraphQL React app van Github.com.

    code language-shell
    $ cd ~/Code
    $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
    
  2. Navigeer naar de map basic-tutorial en open deze in uw IDE.

    code language-shell
    $ cd ~/Code/aem-guides-wknd-graphql/basic-tutorial
    $ code .
    

    React App in VSCode

  3. Werk .env.development bij om verbinding te maken met de AEM as a Cloud Service Publish-service.

    • Stel de waarde van REACT_APP_HOST_URI in op de AEM as a Cloud Service Publish-URL (bijvoorbeeld REACT_APP_HOST_URI=https://publish-p123-e456.adobeaemcloud.com ) en REACT_APP_AUTH_METHOD ''s value to none
    note note
    NOTE
    Zorg ervoor u projectconfiguratie, de modellen van het Fragment van de Inhoud, authored de Fragmenten van de Inhoud, GraphQL eindpunten en voortgeduurde vragen van vorige stappen hebt gepubliceerd.
    Als u bovenstaande stappen hebt uitgevoerd op de lokale AEM Auteur-SDK, kunt u naar http://localhost:4502 en de waarde van REACT_APP_AUTH_METHOD naar basic verwijzen.
  4. Ga vanaf de opdrachtregel naar de map aem-guides-wknd-graphql/basic-tutorial

  5. De React-app starten

    code language-shell
    $ cd ~/Code/aem-guides-wknd-graphql/basic-tutorial
    $ npm install
    $ npm start
    
  6. React app begint op ontwikkelingswijze op http://localhost:3000/. Wijzigingen die tijdens de zelfstudie in de React-app worden aangebracht, worden direct doorgevoerd.

gedeeltelijk uitgevoerde Reageer App

IMPORTANT
Deze React-app is gedeeltelijk geïmplementeerd. Volg de stappen in deze zelfstudie om de implementatie te voltooien. De JavaScript-bestanden die implementatiewerk nodig hebben, hebben de volgende opmerking. Zorg ervoor dat u de code in die bestanden toevoegt/bijwerkt met de code die in deze zelfstudie is opgegeven.
// ​**​**​**​**​**​**​**​**​**​**​**​**​**​**​**​**
// TODO Implementeer dit door de stappen van AEM zelfstudie voor headless uit te voeren.
// ​**​**​**​**​**​**​**​**​**​**​**​**​**​**​**​**

Anatomie van de React-app

De voorbeeldtoepassing React bestaat uit drie hoofdonderdelen:

  1. De map src/api bevat bestanden die worden gebruikt om GraphQL-query's naar AEM te maken.

    • src/api/aemHeadlessClient.js initialiseert en exporteert de AEM Headless-client die wordt gebruikt voor communicatie met AEM
    • src/api/usePersistedQueries.js voert douane React haksterugkeergegevens van AEM GraphQL aan Teams.js en Person.js meningscomponenten uit.
  2. Het src/components/Teams.js dossier toont een lijst van teams en hun leden, door een lijstvraag te gebruiken.

  3. In het bestand src/components/Person.js worden de details van één persoon weergegeven, waarbij een query met één resultaat als parameter wordt gebruikt.

Het object AEMHeadless controleren

Bekijk het aemHeadlessClient.js -bestand voor informatie over het maken van het AEMHeadless -object dat wordt gebruikt om te communiceren met AEM.

  1. Open src/api/aemHeadlessClient.js.

  2. Herzie de lijnen 1-40:

  3. De regels 42-49 zijn het belangrijkst, aangezien zij de AEMHeadless cliënt concretiseren en het voor gebruik door React app uitvoeren.

// Initialize the AEM Headless Client and export it for other files to use
const aemHeadlessClient = new AEMHeadless({
  serviceURL: serviceURL,
  endpoint: REACT_APP_GRAPHQL_ENDPOINT,
  auth: setAuthorization(),
});

export default aemHeadlessClient;

Implementeren om AEM GraphQL doorlopende query's uit te voeren

Als u de algemene functie fetchPersistedQuery(..) wilt implementeren om de AEM GraphQL-query's die u hebt uitgevoerd, uit te voeren, opent u het usePersistedQueries.js -bestand. De functie fetchPersistedQuery(..) gebruikt de functie aemHeadlessClient object runPersistedQuery() om query asynchroon, op belofte gebaseerd gedrag uit te voeren.

Later wordt deze functie aangeroepen door de aangepaste React useEffect -haak om specifieke gegevens van AEM op te halen.

  1. In src/api/usePersistedQueries.js update fetchPersistedQuery(..), lijn 35, met de hieronder code.
/**
 * Private, shared function that invokes the AEM Headless client.
 *
 * @param {String} persistedQueryName the fully qualified name of the persisted query
 * @param {*} queryParameters an optional JavaScript object containing query parameters
 * @returns the GraphQL data or an error message
 */
async function fetchPersistedQuery(persistedQueryName, queryParameters) {
  let data;
  let err;

  try {
    // AEM GraphQL queries are asynchronous, either await their return or use Promise-based syntax
    const response = await aemHeadlessClient.runPersistedQuery(
      persistedQueryName,
      queryParameters
    );
    // The GraphQL data is stored on the response's data field
    data = response?.data;
  } catch (e) {
    // An error occurred, return the error messages
    err = e
      .toJSON()
      ?.map((error) => error.message)
      ?.join(", ");
    console.error(e.toJSON());
  }

  // Return the GraphQL and any errors
  return { data, err };
}

Teams implementeren

Vervolgens ontwikkelt u de functionaliteit om de Teams en hun leden weer te geven in de hoofdweergave van de React-app. Deze functionaliteit vereist:

  • Een nieuwe haak React useEffectin src/api/usePersistedQueries.js die my-project/all-teams voortgeduurde vraag aanhaalt, die een lijst van de Fragmenten van de Inhoud van het Team in AEM terugkeert.
  • Een React component bij src/components/Teams.js die de nieuwe aangepaste React useEffect haak aanhaalt, en de teamgegevens rendert.

Als de hoofdweergave van de app is voltooid, worden de teamgegevens uit AEM ingevuld.

mening van Teams

Stappen

  1. Open src/api/usePersistedQueries.js.

  2. De functie zoeken useAllTeams()

  3. Voeg de volgende code toe om een useEffect -haak te maken die de voortgezette query my-project/all-teams via fetchPersistedQuery(..) aanroept. De haak retourneert ook alleen de relevante gegevens van de AEM GraphQL-respons op data?.teamList?.items, zodat de React-weergavecomponenten zich niet bewust zijn van de bovenliggende JSON-structuren.

    code language-javascript
    /**
     * Custom hook that calls the 'my-project/all-teams' persisted query.
     *
     * @returns an array of Team JSON objects, and array of errors
     */
    export function useAllTeams() {
      const [teams, setTeams] = useState(null);
      const [error, setError] = useState(null);
    
      // Use React useEffect to manage state changes
      useEffect(() => {
        async function fetchData() {
          // Call the AEM GraphQL persisted query named "my-project/all-teams"
          const { data, err } = await fetchPersistedQuery(
            "my-project/all-teams"
          );
          // Sets the teams variable to the list of team JSON objects
          setTeams(data?.teamList?.items);
          // Set any errors
          setError(err);
        }
        // Call the internal fetchData() as per React best practices
        fetchData();
      }, []);
    
      // Returns the teams and errors
      return { teams, error };
    }
    
  4. Openen src/components/Teams.js

  5. Haal in de component Teams React de lijst met teams op van AEM met de useAllTeams() -haak.

    code language-javascript
    import { useAllTeams } from "../api/usePersistedQueries";
    ...
    function Teams() {
      // Get the Teams data from AEM using the useAllTeams
      const { teams, error } = useAllTeams();
      ...
    }
    
  6. Voer de op weergave gebaseerde gegevensvalidatie uit en geef een foutbericht of ladingsindicator weer op basis van de geretourneerde gegevens.

    code language-javascript
    function Teams() {
      const { teams, error } = useAllTeams();
    
      // Handle error and loading conditions
      if (error) {
        // If an error ocurred while executing the GraphQL query, display an error message
        return <Error errorMessage={error} />;
      } else if (!teams) {
        // While the GraphQL request is executing, show the Loading indicator
        return <Loading />;
      }
      ...
    }
    
  7. Tot slot geef de teamgegevens terug. Elk team dat door de GraphQL-query wordt geretourneerd, wordt gerenderd met de meegeleverde subcomponent Team React.

    code language-javascript
    import React from "react";
    import { Link } from "react-router-dom";
    import { useAllTeams } from "../api/usePersistedQueries";
    import Error from "./Error";
    import Loading from "./Loading";
    import "./Teams.scss";
    
    function Teams() {
      const { teams, error } = useAllTeams();
    
      // Handle error and loading conditions
      if (error) {
        return <Error errorMessage={error} />;
      } else if (!teams) {
        return <Loading />;
      }
    
      // Teams have been populated by AEM GraphQL query. Display the teams.
      return (
        <div className="teams">
          {teams.map((team, index) => {
            return <Team key={index} {...team} />;
          })}
        </div>
      );
    }
    
    // Render single Team
    function Team({ title, shortName, description, teamMembers }) {
      // Must have title, shortName and at least 1 team member
      if (!title || !shortName || !teamMembers) {
        return null;
      }
    
      return (
        <div className="team">
          <h2 className="team__title">{title}</h2>
          <p className="team__description">{description.plaintext}</p>
          <div>
            <h4 className="team__members-title">Members</h4>
            <ul className="team__members">
              {/* Render the referenced Person models associated with the team */}
              {teamMembers.map((teamMember, index) => {
                return (
                  <li key={index} className="team__member">
                    <Link to={`/person/${teamMember.fullName}`}>
                      {teamMember.fullName}
                    </Link>
                  </li>
                );
              })}
            </ul>
          </div>
        </div>
      );
    }
    
    export default Teams;
    

Functie Personen implementeren

Met de functionaliteit van Teamsvolledig, voeren wij de functionaliteit uit om de vertoning op de details van een teamlid, of persoon te behandelen.

Deze functionaliteit vereist:

  • Een nieuwe haak React useEffectin src/api/usePersistedQueries.js die de geparameterized my-project/person-by-name voortgeduurde vraag aanhaalt, en één enkel persoonverslag terugkeert.

  • Een component React bij src/components/Person.js die de volledige naam van een persoon als vraagparameter gebruikt, haalt de nieuwe douane React useEffect haak aan, en geeft de persoongegevens terug.

Als u de naam van een persoon hebt geselecteerd in de weergave Teams, wordt de weergave van die persoon weergegeven.

Persoon

  1. Open src/api/usePersistedQueries.js.

  2. De functie zoeken usePersonByName(fullName)

  3. Voeg de volgende code toe om een useEffect -haak te maken die de voortgezette query my-project/all-teams via fetchPersistedQuery(..) aanroept. De haak retourneert ook alleen de relevante gegevens van de AEM GraphQL-respons op data?.teamList?.items, zodat de React-weergavecomponenten zich niet bewust zijn van de bovenliggende JSON-structuren.

    code language-javascript
    /**
     * Calls the 'my-project/person-by-name' and provided the {fullName} as the persisted query's `name` parameter.
     *
     * @param {String!} fullName the full
     * @returns a JSON object representing the person
     */
    export function usePersonByName(fullName) {
      const [person, setPerson] = useState(null);
      const [errors, setErrors] = useState(null);
    
      useEffect(() => {
        async function fetchData() {
          // The key is the variable name as defined in the persisted query, and may not match the model's field name
          const queryParameters = { name: fullName };
    
          // Invoke the persisted query, and pass in the queryParameters object as the 2nd parameter
          const { data, err } = await fetchPersistedQuery(
            "my-project/person-by-name",
            queryParameters
          );
    
          if (err) {
            // Capture errors from the HTTP request
            setErrors(err);
          } else if (data?.personList?.items?.length === 1) {
            // Set the person data after data validation
            setPerson(data.personList.items[0]);
          } else {
            // Set an error if no person could be found
            setErrors(`Cannot find person with name: ${fullName}`);
          }
        }
        fetchData();
      }, [fullName]);
    
      return { person, errors };
    }
    
  4. Openen src/components/Person.js

  5. In de component Person React, ontleedt de fullName routeparameter, en haalt de persoongegevens van AEM gebruikend de usePersonByName(fullName) haak.

    code language-javascript
    import { useParams } from "react-router-dom";
    import { usePersonByName } from "../api/usePersistedQueries";
    ...
    function Person() {
      // Read the person's `fullName` which is the parameter used to query for the person's details
      const { fullName } = useParams();
    
      // Query AEM for the Person's details, using the `fullName` as the filtering parameter
      const { person, error } = usePersonByName(fullName);
      ...
    }
    
  6. Voer op weergave gebaseerde gegevensvalidatie uit en geef een foutbericht of ladingsindicator weer op basis van de geretourneerde gegevens.

    code language-javascript
    function Person() {
      // Read the person's `fullName` which is the parameter used to query for the person's details
      const { fullName } = useParams();
    
      // Query AEM for the Person's details, using the `fullName` as the filtering parameter
      const { person, error } = usePersonByName(fullName);
    
      // Handle error and loading conditions
      if (error) {
        return <Error errorMessage={error} />;
      } else if (!person) {
        return <Loading />;
      }
      ...
    }
    
  7. Tot slot geef de persoongegevens terug.

    code language-javascript
    import React from "react";
    import { useParams } from "react-router-dom";
    import { usePersonByName } from "../api/usePersistedQueries";
    import { mapJsonRichText } from "../utils/renderRichText";
    import Error from "./Error";
    import Loading from "./Loading";
    import "./Person.scss";
    
    function Person() {
      // Read the person's `fullName` which is the parameter used to query for the person's details
      const { fullName } = useParams();
    
      // Query AEM for the Person's details, using the `fullName` as the filtering parameter
      const { person, error } = usePersonByName(fullName);
    
      // Handle error and loading conditions
      if (error) {
        return <Error errorMessage={error} />;
      } else if (!person) {
        return <Loading />;
      }
    
      // Render the person data
      return (
        <div className="person">
          <img
            className="person__image"
            src={process.env.REACT_APP_HOST_URI+person.profilePicture._path}
            alt={person.fullName}
          />
          <div className="person__occupations">
            {person.occupation.map((occupation, index) => {
              return (
                <span key={index} className="person__occupation">
                  {occupation}
                </span>
              );
            })}
          </div>
          <div className="person__content">
            <h1 className="person__full-name">{person.fullName}</h1>
            <div className="person__biography">
              {/* Use this utility to transform multi-line text JSON into HTML */}
              {mapJsonRichText(person.biographyText.json)}
            </div>
          </div>
        </div>
      );
    }
    
    export default Person;
    

Probeer de app

Herzie app http://localhost:3000/en klik Leden verbindingen. Ook kunt u meer teams en/of leden aan de Alpha van het Team toevoegen door de Fragmenten van de Inhoud in AEM toe te voegen.

IMPORTANT
Om uw implementatieveranderingen te verifiëren of als u app die na bovengenoemde veranderingen werkt niet kunt krijgen, verwijs basis-tutorialoplossingstak.

Onder de hood

Open browser Hulpmiddelen van de Ontwikkelaar > Netwerk en Filter voor all-teams verzoek. De GraphQL API-aanvraag /graphql/execute.json/my-project/all-teams wordt uitgevoerd tegen http://localhost:3000 en NOT tegen de waarde van REACT_APP_HOST_URI , bijvoorbeeld <https://publish-pxxx-exxx.adobeaemcloud.com . De verzoeken worden gemaakt tegen het React toepassingsdomein omdat volmachtsopstellinggebruikend http-proxy-middleware module wordt toegelaten.

GraphQL API verzoek via Volmacht

Bekijk het hoofd ../setupProxy.js dossier en binnen ../proxy/setupProxy.auth.**.js dossiers merken hoe /content en /graphql de wegen proxied zijn en erop wijzen het geen statisch middel is.

module.exports = function(app) {
  app.use(
    ['/content', '/graphql'],
  ...

Het gebruiken van de lokale volmacht is geen geschikte optie voor productieplaatsing en meer details kunnen bij sectie van de Plaatsing van de Productie worden gevonden.

Gefeliciteerd! congratulations

Gefeliciteerd! U hebt de React-app gemaakt om gegevens van AEM GraphQL API's te verbruiken en weer te geven als onderdeel van de basiszelfstudie.

recommendation-more-help
e25b6834-e87f-4ff3-ba56-4cd16cdfdec4