Extraire des données à partir d'une API REST dans une application DOM virtuelle Oracle JET

Présentation

Ce tutoriel explique comment accéder à un service REST, l'intégrer à votre application DOM virtuelle Oracle JavaScript Extension Toolkit (Oracle JET), et lier des données à une vue de liste dans votre interface utilisateur.

Objectifs

Dans ce tutoriel, vous apprendrez à créer des instances de la classe RESTDataProvider. Cette classe représente les données disponibles à partir des services REST basés sur JSON.

Conditions requises

Tâche 1 : Télécharger l'application DOM virtuelle de démarrage

Ignorez cette tâche si vous continuez à travailler dans une application que vous avez créée dans le cheminement d'apprentissage précédent.

  1. Renommez jet-virtual-dom-app-temp.zip JET-Virtual-DOM-app.zip. Extrayez le contenu dans le répertoire JET-Virtual-DOM-app.

  2. Accédez au répertoire JET-Virtual-DOM-app et restaurez l'application DOM virtuelle Oracle JET.

    npm install
    

    L'application DOM virtuelle est prête à l'emploi.

Tâche 2 : Accéder au service REST

Cliquez sur le lien sommet pour voir les données REST du point d'extrémité de ressource Activités.

Les données contiennent une liste d'activités avec divers attributs.

{
  "items": [
      {
      "id": 1,
      "name": "Baseball",
      "short_desc": "Equipment we carry for baseball players.",
      "image": "css/images/product_images/baseball.jpg"
      },
   . . .
   ],
   "hasMore": false,
   "limit": 25,
   "offset": 0,
   "count": 4,
   "links": [
      {
      "rel": "self",
      "href": "https://apex.oracle.com/pls/apex/oraclejet/lp/activities/"
      },
      . . .
   ]
}

Familiarisez-vous avec les données et les propriétés renvoyées par le point d'extrémité. Vous devrez comprendre ces détails lorsque vous créerez une instance de RESTDataProvider plus tard dans ce tutoriel. Notez, par exemple, comment le point d'extrémité retourne une propriété items qui référence une série d'activités individuelles.

Tâche 3 : Créer un fournisseur de données pour extraire les données d'activité

  1. Naviguez jusqu'au répertoire JET-Virtual-DOM-app/src/components/ et ouvrez le fichier ParentContainer1.tsx dans un éditeur.

  2. Au début du fichier ParentContainer1.tsx, importez le module RESTDataProvider et supprimez ou mettez en commentaire les énoncés d'importation pour le module MutableArrayDataProvider et le fichier store_data.json.

    Nous importons également le crochet useMemo que nous utiliserons lors de la création ultérieure de RESTDataProvider.

    import { h } from "preact";
    . . .
    // import MutableArrayDataProvider = require("ojs/ojmutablearraydataprovider");
    // import * as storeData from "text!./store_data.json";
    import { RESTDataProvider } from "ojs/ojrestdataprovider";
    import { useState, useMemo } from "preact/hooks";
    . . .
    
  3. Créez une variable keyattributes et une variable restServerURLActivities qui référencent l'attribut de clé d'activité et le point d'extrémité REST que vous transmettez à l'instance RESTDataProvider que vous créerez à l'étape suivante.

    let keyAttributes: string = 'id';
    // REST endpoint that returns Activity data
    const restServerURLActivities: string =
      'https://apex.oracle.com/pls/apex/oraclejet/lp/activities/';
    
  4. Créez une nouvelle variable activityDataProvider qui référence le module RESTDataProvider et supprimez ou mettez en commentaire la variable activityDataProvider préexistante qui référence le module MutableArrayDataProvider.

    Nous créons la nouvelle variable activityDataProvider dans la fonction ParentContainer1 et nous l'encapsulons dans un crochet useMemo pour nous assurer que l'instance de fournisseur de données est recréée uniquement si les données du fournisseur de données changent réellement.

    const ParentContainer1 = () => {
    
    const activityDataProvider = useMemo(() => new RESTDataProvider<Activity["id"], Activity>({
       keyAttributes: keyAttributes,
       url: restServerURLActivities,
       transforms: {
          fetchFirst: {
          request: async (options) => {
             const url = new URL(options.url);
             const { size, offset } = options.fetchParameters;
             url.searchParams.set("limit", String(size));
             url.searchParams.set("offset", String(offset));
             return new Request(url.href);
          },
          response: async ({ body }) => {
             const { items, totalSize, hasMore } = body;
             return { data: items, totalSize, hasMore };
          },
          },
       },
     }), [])
    . . .
    

    Note : La fonction response ci-dessus qui extrait des données et d'autres propriétés du corps de la réponse du point d'extrémité doit retourner un objet avec une propriété data. Étant donné que le point d'extrémité avec lequel nous travaillons retourne une propriété items, nous affectons cette dernière propriété à data dans la fonction de réponse.

  5. Enregistrez le fichier ParentContainer1.tsx.

    Votre fichier ParentContainer1.tsx doit ressembler à ParentContainer1-a.tsx.txt.

  6. Naviguez jusqu'au répertoire JET-Virtual-DOM-app/src/components/Activity et ouvrez le fichier ActivityContainer.tsx dans un éditeur.

  7. Au début du fichier ActivityContainer.tsx, importez le module RESTDataProvider et mettez en commentaire ou supprimez l'énoncé d'importation pour le module MutableArrayDataProvider.

       import { h, ComponentProps } from "preact";
       . . .
       // import MutableArrayDataProvider = require("ojs/ojmutablearraydataprovider");
       import { RESTDataProvider } from "ojs/ojrestdataprovider";
       . . .
    
    
  8. Dans l'alias de type Props, modifiez la propriété facultative data pour référencer le type RESTDataProvider au lieu du type préexistant MutableArrayDataProvider<Activity["id"], Activity>.

       type Props = {
          data?: RESTDataProvider<Activity["id"], Activity>;
          // data?: MutableArrayDataProvider<Activity["id"], Activity>;
       . . .
       };
    
  9. Enregistrez le fichier ActivityContainer.tsx.

    Votre fichier ActivityContainer.tsx doit ressembler à ActivityContainer.tsx.txt.

Tâche 4 : Ajouter un programme de traitement des erreurs pour gérer un échec d'extraction de données

L'instance RESTDataProvider fournit une option d'erreur que vous pouvez utiliser pour appeler une fonction de rappel lorsqu'une tentative d'extraction de données échoue. Vous allez mettre en oeuvre cette fonction pour le scénario où une tentative d'extraction de la liste des activités échoue.

  1. Dans le fichier ParentContainer1.tsx du répertoire JET-Virtual-DOM-app/src/components/, importez le crochet useRef à partir de Preact.

    . . .
    import { RESTDataProvider } from "ojs/ojrestdataprovider";
    import { useState, useMemo, useRef } from "preact/hooks";
    . . .
    
  2. Dans la variable activityDataProvider qui référence RESTDataProvider, ajoutez l'option error et une référence à la fonction de rappel qu'elle appelle (fetchErrorHandler).

    const ParentContainer1 = () => {
    
       const activityDataProvider = useMemo(() => new RESTDataProvider<Activity["id"], Activity>({
          keyAttributes: keyAttributes,
          url: restServerURLActivities,
          error: fetchErrorHandler,
          transforms: {
          . . .
    
  3. Avant la variable activityDataProvider, ajoutez le code pour fetchErrorHandler et les crochets (useState et useRef) que nous utilisons pour déterminer si la tentative d'extraction des données a réussi.

    . . .
    const ParentContainer1 = () => {
    
    const [fetchStatus, setFetchStatus] = useState(true);
    const fetchError = useRef<string>();
    
    const fetchErrorHandler = (errorDetail: RESTDataProvider.FetchErrorDetail<number, Activity> |
                                            RESTDataProvider.FetchResponseErrorDetail<number, Activity>) => {
       setFetchStatus(false);
       if (errorDetail.hasOwnProperty('response')) {
          fetchError.current = `${(errorDetail as RESTDataProvider.FetchResponseErrorDetail<number, Activity>).response.status}`;
       }
       else {
          fetchError.current = (errorDetail as RESTDataProvider.FetchErrorDetail<number, Activity>).error.message;
       }
    }
    
    const activityDataProvider = new RESTDataProvider<Activity["id"], Activity>({
    . . .
    
  4. Dans l'énoncé de retour à la fin du fichier ParentContainer1.tsx, ajoutez une vérification qui détermine si vous affichez la liste des activités ou un message dans le cas où la tentative d'extraction des données a échoué.

    . . .
    return (
       <div>
          {fetchStatus ? (
          <div id="parentContainer1" class="oj-flex oj-flex-init">
             <ActivityContainer data={activityDataProvider} onActivityChanged={activityChangedHandler} />
             {showActivityItems() && (<ParentContainer2 activity={selectedActivity} />)}
             {!showActivityItems() && (<h4 class="oj-typography-subheading-sm">Select activity to view items</h4>)}
          </div>) :
          (<p>Sorry that we couldn't get your product information right now. Please contact your system administrator.</p>
          )}
       </div>
    );
    };
    
    export default ParentContainer1;
    
  5. Enregistrez le fichier ParentContainer1.tsx.

    Votre fichier ParentContainer1.tsx doit être similaire à ParentContainer1-b.tsx.txt.

Tâche 5 : Créer un fournisseur de données pour extraire les données d'élément

Utilisez une autre instance RESTDataProvider pour extraire un sous-ensemble des données, la liste des éléments d'une activité particulière. Pour ce faire, vous devez fournir une nouvelle URL contenant l'ID activité sélectionné.

  1. Naviguez jusqu'au répertoire JET-Virtual-DOM-app/src/components/ et ouvrez le fichier ParentContainer2.tsx dans un éditeur.

  2. Au début du fichier ParentContainer2.tsx, importez le module RESTDataProvider et supprimez ou mettez en commentaire les énoncés d'importation pour le module MutableArrayDataProvider et le fichier store_data.json. Importez également l'interface TextFilter que nous utiliserons lorsque nous activerons la fonction de filtrage dans l'instance RESTDataProvider que nous créerons.

    import { h } from "preact";
    . . .
    import { RESTDataProvider } from "ojs/ojrestdataprovider";
    import { TextFilter } from "ojs/ojdataprovider";
    
    // import MutableArrayDataProvider = require("ojs/ojmutablearraydataprovider");
    // import * as storeData from "text!./store_data.json";
    . . .
    
    
  3. Après l'alias de type Item, créez une variable baseServiceUrl pour référencer le point d'extrémité REST que vous transmettez à l'instance RESTDataProvider que vous créerez à l'étape suivante.

    type Item = {
       . . .
     };
    
    const baseServiceUrl =
      "https://apex.oracle.com/pls/apex/oraclejet/lp/activities/";
    
  4. Créez une instance initiale de RESTDataProvider que vous transmettrez aux crochets Preact useState et useEffect au cours des étapes suivantes.

       const baseServiceUrl = 'https://apex.oracle.com/pls/apex/oraclejet/lp/activities/';
    
       let INIT_DATAPROVIDER = new RESTDataProvider<ActivityItem['id'], ActivityItem>({
       keyAttributes: 'id',
       url: baseServiceUrl,
       transforms: {
          fetchFirst: {
             request: null!,
             response: (): any => {
             return { data: [] };
             },
          },
       },
       });
    
  5. Commenter ou supprimer le code préexistant qui a créé une variable pour lire les données du fichier store_data.json et qui a créé une instance initiale de MutableArrayDataProvider.

       // const activityData = JSON.parse(storeData);
       // let activityItemsArray = activityData[0].items;
    
       // // Create data provider instance for the array of activity items for the selected activity
       // const INIT_DATAPROVIDER = new MutableArrayDataProvider<ActivityItem["id"], ActivityItem>(activityItemsArray, {
       //   keyAttributes: "id",
       // })
    
  6. Dans la fonction ParentContainer2, remplacez le crochet useEffect existant qui gère l'instance de MutableArrayDataProvider par une nouvelle définition qui crée une valeur RESTDataProvider pour les éléments d'activité correspondant à l'ID activité sélectionné. Cette nouvelle définition comprend également un filtre de texte à filtrer sur le champ de l'élément d'activité name.

    const ParentContainer2 = (props: Props) => {
    . . .
    useEffect(() => {
       setactivityItemDP(
          new RESTDataProvider<ActivityItem["id"], ActivityItem>({
          keyAttributes: "id",
          capabilities: {
             filter: {
                textFilter: true,
             },
          },
          url: baseServiceUrl + "/" + props.activity?.id + "/items/",
          textFilterAttributes: ["name"],
          transforms: {
             fetchFirst: {
                request: async (options) => {
                const url = new URL(options.url);
                const { size, offset } = options.fetchParameters;
                url.searchParams.set("limit", String(size));
                url.searchParams.set("offset", String(offset));
                const filterCriterion = options.fetchParameters
                   .filterCriterion as TextFilter<Item>;
                const { textFilterAttributes } = options.fetchOptions;
                if (
                   filterCriterion &&
                   filterCriterion.text &&
                   textFilterAttributes
                ) {
                   const { text } = filterCriterion;
                   textFilterAttributes.forEach((attribute) => {
                      url.searchParams.set(attribute, text);
                   });
                }
    
                return new Request(url.href);
                },
                response: async ({ body }) => {
                const { items, totalSize, hasMore } = body;
                return { data: items, totalSize, hasMore };
                },
             },
          },
          })
       );
    }, [props.activity]);
    
    return (
    . . .
    
  7. Enregistrez le fichier ParentContainer2.tsx.

    Votre fichier ParentContainer2.tsx doit ressembler à ParentContainer2.tsx.txt.

  8. Naviguez jusqu'au répertoire JET-Virtual-DOM-app/src/components/ActivityItem et ouvrez le fichier ActivityItemContainer.tsx dans un éditeur.

  9. Au début du fichier ActivityItemContainer.tsx, importez le module RESTDataProvider et commentez ou supprimez l'énoncé d'importation pour le module MutableArrayDataProvider.

    import { h, ComponentProps } from "preact";
    . . .
    // import MutableArrayDataProvider = require("ojs/ojmutablearraydataprovider");
    import { RESTDataProvider } from "ojs/ojrestdataprovider";
    . . .
    
  10. Dans l'alias de type Props, modifiez la propriété data pour référencer le type RESTDataProvider au lieu du type préexistant MutableArrayDataProvider<Activity["id"], Activity>.

    type Props = {
      // data?: MutableArrayDataProvider<ActivityItem["id"], ActivityItem>;
      data?: RESTDataProvider<ActivityItem['id'], ActivityItem>;
      selectedActivity: Item | null;
      onItemChanged: (item: Item) => void;
    };
    
  11. Enregistrez le fichier ActivityItemContainer.tsx.

    Votre fichier ActivityItemContainer.tsx doit ressembler à ActivityItemContainer.tsx.txt.

Tâche 6 : Tester l'application DOM virtuelle

  1. Dans la fenêtre de terminal, accédez au répertoire JET-Virtual-DOM-app et exécutez l'application DOM virtuelle.

    npx ojet serve
    
  2. Dans la fenêtre du navigateur, affichez les modifications dynamiques de votre application DOM virtuelle.

    Écran Enregistrements extraits

  3. Fermez la fenêtre ou l'onglet du navigateur qui affiche votre application DOM virtuelle en cours d'exécution.

  4. Dans la fenêtre de terminal, appuyez sur Ctrl+C et, si vous y êtes invité, entrez y pour quitter la tâche par lots d'outils Oracle JET.

  5. Dans la fenêtre de terminal, exécutez l'application DOM virtuelle à l'aide des arguments de ligne de commande supplémentaires suivants.

    npx ojet serve --server-port=8144 --livereload-port=8145
    

    À cette occasion, l'application DOM virtuelle affiche le message suivant car le service REST auquel elle fait confiance accepte uniquement les demandes sur le port du serveur que la commande ojet serve utilise par défaut (8000), de sorte que la tentative d'extraction du service REST par RESTDataProvider a échoué.

    Sorry that we couldn't get your product information right now. Please contact your system administrator.
    

Étape suivante

Passez au tutoriel suivant dans ce module.

Ce tutoriel fait partie du module Opérations CRUD à l'aide d'un service REST.

Vous pouvez retourner à la page principale du cheminement d'apprentissage DOM virtuel pour accéder à tous les modules de la création d'applications DOM virtuelles.

Ressources d'apprentissage supplémentaires

Explorez d'autres laboratoires sur le site docs.oracle.com/learn ou accédez à plus de contenu d'apprentissage gratuit sur le canal Oracle Learning YouTube. De plus, visitez education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.

Pour obtenir la documentation sur le produit, visitez Oracle Help Center.