Beispiele rest json: Unterschied zwischen den Versionen

Aus bafbal.de
Zur Navigation springen Zur Suche springen
Zeile 141: Zeile 141:
  
 
[[Datei:rest_baum.png|866px]]
 
[[Datei:rest_baum.png|866px]]
 +
 +
==Ein VL-Segment füllen==
 +
 +
Wenn wir https://api.predic8.de/shop/products/3 aufrufen, dann erhalten wir die Details zum Produkt zurück.
 +
 +
{
 +
    "name": "Bananas",
 +
    "price": 0.99,
 +
    "photo_url": "/shop/products/3/photo",
 +
    "category_url": "/shop/categories/Fruits",
 +
    "vendor_url": "/shop/vendors/672"
 +
}
 +
 +
Diese wollen wir nun in einem VL-Segment anzeigen. Das sieht erst mal wie folgt aus:
 +
 +
#grid
 +
 +
#prim  as=Y 
 +
#cat  as=Y    c="Daten aus https://api.predic8.de/shop/products/"
 +
 +
#vl_seg  cc=5  w1=70  w2=50  w3=20  w4=70  w5=200  n=vl 
 +
#vl_line  c1=ID  c2=$FND(s,id)  nd2=Y  nvi2=neu  c3=" "  c4=Name  f5=name
 +
#vl_line  c1=Preis  f2=price  y2=curr  a2=d2  c3=" "  c4=Kategorie  f5=category_url 
 +
#vl_line  c1=Lieferant  c3=" "  c4=Name  f5=vendor_url 
 +
 +
#http_request  y=get  se=N  response=resp  isc=Y    url=https://api.predic8.de/shop/products/$FND(s,id) 
 +
#json_parse  json=$VAR(resp)
 +
 +
#vl_data  q=json  k=id    isc=Y 
 +
 +
[[Datei:rest_vl1.png|851px]]

Version vom 31. Dezember 2022, 12:55 Uhr

Daten von einem REST-Server holen, anzeigen und bearbeiten

Der REST-Server

Unter https://api.predic8.de/shop/products/ ist ein REST-Server zu finden, der als Beispiel-Server der Allgemeinheit zur Verfügung steht. Der Aufruf der URL gibt die folgenden Daten zurück:

{
   "meta": {
       "count": 32,
       "limit": 10,
       "page": 1,
       "next_url": "/shop/products/?page=2&limit=10"
   },
   "products": [
       {
           "name": "Bananas",
           "product_url": "/shop/products/3"
       },
       {
           "name": "Oranges",
           "product_url": "/shop/products/10"
       },
         ...
       {
           "name": "Apple",
           "product_url": "/shop/products/18"
       },
       {
           "name": "Green Grapes",
           "product_url": "/shop/products/11"
       }
   ]
}

Daten von mehreren Seiten zusammenfassen

Die Daten sind auf mehrere Seiten aufgeteilt. Für unsere Zwecke müssen wir sie zusammenfassen. Dazu eignet sich die Prozedur #http_loop_json.

In solchen Fällen hat es sich bewährt, das erst mal als Konsolen-Anwendung zu realisieren, und das dann in die konkrete Anwendung zu kopieren. Diese Konsolen-Anwendung würde wie folgt aussehen:

#frm  c="c_test_json"   y=console

#code   url=https://api.predic8.de/shop/products/
#code   nurl="https://api.predic8.de$JSON_VALUE(1,meta.next_url)"
#code   ready=$EMPTY($JSON_VALUE(1,meta.next_url))
#http_loop_json   y=get    se=N   $CODE$   isc=Y   m=20

#coutl $JSON_TEXT(1,frm)

#cout  c="c_test_json executed"

Die Prozedur #http_loop_json verwendet y=get als Method, wir wollen schließlich Daten abfragen. Als url verwenden wir die Seite https://api.predic8.de/shop/products/.

Sobald die erste Seite da ist, wird die nächste Seite aufgerufen, und deren URL wird mit nurl ("next URL") angegeben. Dazu wird aus dem Anwort-JSON das Feld meta-next_url extrahiert ($JSON_VALUE(1,meta.next_url), #http_loop_json arbeitet auf dem ersten JSON), davor wird der Rest der erforderlichen URL ergänzt. Daneben benötigt #http_loop_json auch noch einen Hinweis, wann die Schleife beendet werden soll, das ist dann der Fall, wenn meta.next_url leer ist. Sicherheitshalber setzt man bei #http_loop_json noch m=20, nach spätestens 20 Seiten wird also auch abgebrochen.

Da der Server ein abgelaufenes Zertifikat hat, setzen wir isc=Y. Anschließend wird mit #coutl $JSON_TEXT(1,frm) das Ergebnis formatiert ausgegeben:

{
 "products": [
   {
     "name": "Bananas",
     "product_url": "/shop/products/3"
   },
   {
     "name": "Oranges",
     "product_url": "/shop/products/10"
   },
   {
     "name": "Pineapples",
     "product_url": "/shop/products/33"
   },
     ...
   {
     "name": "Pistachio",
     "product_url": "/shop/products/76"
   }
 ],
 "meta": {
   "count": 32,
   "limit": 10,
   "page": 4,
   "previous_url": "/shop/products/?page=3&limit=10"
 }
}

Die Prozedur #http_loop_json fügt bei Arrays auf der obersten Ebene (hier products) weitere Array-Elemente hinzu (die Anzeige eben wurde an der Stelle ... gekürzt, die Liste wäre sonst deutlich länger), während Objekte überschrieben werden (hier meta).

ID extrahieren

Wir können später die ID gebrauchen, von daher wollen wir diese auch extrahieren.

#http_loop_json   y=get    se=N   $CODE$   isc=Y   m=20

#cmd_clear #json_chgdata   n=json   path=id   add=Y   is=N   z="$STREXTR($JSON_DATA(json,product_url),ffe,/shop/products/)"
#json_loop   n=json   er=1   path=products

#coutl $JSON_TEXT(1,frm)

Vor der Ausgabe fügen wir eine #json_loop ein, die durch das Array products geht und für jeden Eintrag die zuvor definierte lokale Prozedur aufruft. Hier wird mit #json_chgdata das jeweilige Element in der Loop geändert, genau genommen - da add=Y - wird ein neues Element namens path=id dem jeweiligen Array-Element hinzu. Der Wert von id wird mit dem Parameter z bestimmt. Hier holen wir die product_url aus dem JSON und extrahieren alles, was nach /shop/products/ kommt.

Die Ergebnismenge (Ausschnitt) sieht nun wie folgt aus:

{
 "products": [
   {
     "name": "Bananas",
     "product_url": "/shop/products/3",
     "id": 3
   },
   {
     "name": "Oranges",
     "product_url": "/shop/products/10",
     "id": 10
   },
     ...

Einen Tree füllen

Nun wollen wir mit den Daten in eine konventionelle Oberfläche und legen mit dem Wizard das Kommando xtestrest an. Für das Sub-Kommando xtestrest_flt verwenden wir

#tree_clear

#tree_add   u=root   c=Produkte   si=Y   s="#page_fill   d=xtestrest_page_produkte"  o=xtestrest_open(produkte)

Die Produkte laden wir dann in xtestrest_open.

~ $ICP(0,produkte)
#code   url=https://api.predic8.de/shop/products/
#code   nurl="https://api.predic8.de$JSON_VALUE(1,meta.next_url)"
#code   ready=$EMPTY($JSON_VALUE(1,meta.next_url))
#http_loop_json   y=get    se=N   $CODE$   isc=Y   m=20

#cmd_clear #json_chgdata   n=json   path=id   add=Y   is=N   z="$STREXTR($JSON_DATA(json,product_url),ffe,/shop/products/)"
#json_loop   n=json   er=1   path=products

#tree_fill   u=o   q=json   path=products   c1=id   c2=name   s="#page_fill   d=xtestrest_page_produkt   rs=Y"  

~~

Bis auf #tree_fill ist das vom eben erstellten Konsolen-Kommando 1:1 kopiert. Als Datenquelle geben wir q=json ein, also werden die Daten aus dem ersten JSON geholt. Mit ID und name werden die entsprechenden Werte aus dem JSON geholt.

Rest baum.png

Ein VL-Segment füllen

Wenn wir https://api.predic8.de/shop/products/3 aufrufen, dann erhalten wir die Details zum Produkt zurück.

{
   "name": "Bananas",
   "price": 0.99,
   "photo_url": "/shop/products/3/photo",
   "category_url": "/shop/categories/Fruits",
   "vendor_url": "/shop/vendors/672"
}

Diese wollen wir nun in einem VL-Segment anzeigen. Das sieht erst mal wie folgt aus:

#grid

#prim  as=Y  
#cat  as=Y     c="Daten aus https://api.predic8.de/shop/products/"

#vl_seg   cc=5   w1=70   w2=50  w3=20   w4=70   w5=200   n=vl   
#vl_line   c1=ID   c2=$FND(s,id)   nd2=Y   nvi2=neu   c3=" "   c4=Name   f5=name
#vl_line   c1=Preis   f2=price   y2=curr   a2=d2   c3=" "   c4=Kategorie   f5=category_url   
#vl_line   c1=Lieferant   c3=" "   c4=Name   f5=vendor_url   

#http_request   y=get   se=N   response=resp   isc=Y    url=https://api.predic8.de/shop/products/$FND(s,id)  
#json_parse   json=$VAR(resp)

#vl_data   q=json   k=id    isc=Y  

Rest vl1.png