Quickstarters
Wie man ein E-Commerce-Backend aufbaut?
86 min
in diesem praktischen tutorial erstellen sie eine rocksolide, vollständige e commerce anwendung von grund auf mit einem backend as a service auf dem weg dorthin werden sie meistern sichere benutzerauthentifizierung, die sicherstellt, dass nur autorisierte käufer und administratoren zugang erhalten intuitive datenmodelle, die zur unterstützung von produktkatalogen, kundenprofilen und bestellhistorien entwickelt wurden restful und echtzeit apis, damit ihr frontend immer mit dem inventar, den warenkörben und dem checkout status synchron bleibt automatisierte bereitstellungspipelines, die es ihnen ermöglichen, updates mit zuversicht zu pushen und zurückzurollen, falls etwas schiefgeht am ende haben sie nicht nur einen produktionsbereiten shop, sondern auch das architektonische wissen, um jede webanwendung zu erweitern, zu skalieren und abzusichern erforschen sie die fertige e commerce anwendung in aktion unter web e commerce app lass uns anfangen! wichtige erkenntnisse schnelle backend einrichtung starten und konfigurieren sie ein vollständiges e commerce datenmodell in minuten mit der low code plattform von back4app sichere benutzerflüsse implementieren sie robuste anmeldungen, logins und abmeldungen mit cloud code und sitzungstoken api first entwicklung greifen sie über automatisch generierte rest/graphql endpunkte und das parse sdk für jeden client auf ihre daten zu geschäftslogik in cloud code zentralisieren sie kernoperationen—produkt crud, warenkorbverwaltung und checkout—während sie berechtigungen durchsetzen containerisierte frontend bereitstellung verpacken und bereitstellen sie ihr next js storefront in der back4app webbereitstellung für konsistentes, skalierbares hosting voraussetzungen und umgebungssetup um dieses tutorial zu befolgen, stellen sie sicher, dass sie folgendes haben ein back4app konto sie können sich kostenlos auf der back4app website https //www back4app com/signup anmelden node js installiert, damit sie abhängigkeiten mit npm oder yarn verwalten können vertrautheit mit javascript zum schreiben von benutzerdefiniertem cloud code und zur nutzung des sdk von back4app grundlegendes verständnis von e commerce konzepten wie benutzerautorisierung, produktkatalogverwaltung und auftragsabwicklung git zur versionskontrolle, damit sie änderungen verfolgen, bei bedarf zurücksetzen und nahtlos zusammenarbeiten können die sicherstellung, dass sie die oben genannten elemente haben, wird ihnen helfen, die möglichkeiten von back4app zu maximieren und wichtige e commerce funktionen zu implementieren, ohne ins stocken zu geraten erstellen und konfigurieren ihres back4app kontos um mit der einrichtung ihres e commerce backends auf back4app zu beginnen, besuchen sie back4app https //www back4app com und klicken sie auf registrieren geben sie ihre e mail adresse ein, wählen sie ein sicheres passwort und geben sie alle erforderlichen details an sobald sie ihre e mail verifiziert haben, erhalten sie zugriff auf das back4app dashboard back4app anmeldeseite wählen sie im dashboard neue app erstellen oder neue app erstellen und geben sie ihrem projekt einen namen – etwas beschreibendes, damit sie es später leicht finden können bestätigen sie ihre auswahl und warten sie, bis der prozess zur erstellung der app abgeschlossen ist das projekt dashboard zeigt klassen, analysen und konfigurationen an eine back4app app erstellen mit diesen schritten haben sie eine e commerce plattform erstellt im nächsten abschnitt werden sie ihr datenschema entwerfen und sich auf das produktmanagement, die auftragsabwicklung und die benutzerauthentifizierung vorbereiten entwurf ihres e commerce datenschemas um ein skalierbares und wartbares backend für ihre e commerce plattform zu implementieren, organisieren sie ihre daten um sieben kern tabellen benutzer , käufer , verkäufer , produkt , warenkorb , bestellung , und bestelldetails jede tabelle spielt eine fokussierte rolle bei der unterstützung der gesamtfunktionalität des systems, und zusammen bilden sie ein normalisiertes und effizientes schema beginnen sie mit der user tabelle, die als grundlage für alle benutzeridentitäten dient jede person auf ihrer plattform—unabhängig von ihrer rolle—wird sich über diese tabelle authentifizieren fügen sie felder wie username , password , und email hinzu, um die grundlegende anmeldung zu verwalten fügen sie emailverified hinzu, um den verifizierungsstatus zu verfolgen, und authdata falls sie planen, drittanbieter logins oder oauth flows zu unterstützen um zwischen käufern und verkäufern zu unterscheiden, definieren sie ein usertype feld dieses feld ermöglicht es ihnen, den zugriff zu steuern, ansichten zu verwalten und funktionalitäten basierend auf benutzerrollen zu trennen, während sie dennoch ein einheitliches, konsistentes anmeldesystem beibehalten anstatt alle benutzertypen in einer tabelle zu mischen, erstellen sie separate buyer und seller tabellen, die über das user feld auf userid verweisen dies ermöglicht es ihnen, rollenspezifische daten zu speichern, ohne die zentrale benutzertabelle aufzublähen die buyer tabelle kann kaufbezogene felder wie paymentinfo und shippingaddress , die für den checkout und lieferprozess unerlässlich sind, enthalten im gegensatz dazu verfolgt die seller tabelle attribute, die für händler relevant sind, wie storename , bio , und phonenumber mit dieser trennung können sie käufer und verkäufer unabhängig verwalten und abfragen, während sie sie dennoch mit ihrer gemeinsamen identität in user verknüpfen ihr produkt tisch ist der ort, an dem artikel zum verkauf gespeichert werden jedes produkt sollte grundlegende beschreibende informationen wie einen namen, eine detaillierte beschreibung und ein oder mehrere bilder enthalten für preis und bestandsverwaltung möchten sie auch felder für den preis, den verfügbarkeitsstatus über einen booleschen isactive , und die stückzahl unter quantityavailable entscheidend ist, dass jedes produkt mit dem verkäufer verknüpft sein muss, der es aufgeführt hat um diese beziehung herzustellen, fügen sie einen sellerid fremdschlüssel hinzu, der auf die seller tabelle verweist diese struktur stellt sicher, dass jeder artikel in ihrem katalog mit einem verifizierten händler verbunden ist und macht die verkäuferspezifische filterung einfach um das verhalten vor dem kauf zu steuern, führen sie eine cart tabelle ein jeder warenkorb gehört zu einem benutzer, also fügen sie ein userid feld hinzu, das auf user verweist speichern sie ein array von warenkorb items , die jeweils ein produkt darstellen, das der benutzer kaufen möchte, zusammen mit allen metadaten, die sie benötigen, wie menge oder ausgewählte optionen die verfolgung des totalprice des warenkorbs ermöglicht es ihnen, schnell checkout zusammenfassungen anzuzeigen, ohne werte bei jeder anfrage neu zu berechnen dieses setup unterstützt grundlegende warenkorb funktionalität und vereinfacht die sitzungspersistenz wenn sie die array struktur als einschränkend empfinden – insbesondere wenn sie komplexere artikelbezogene daten erfassen müssen – können sie die artikel später immer in eine separate tabelle umstrukturieren wenn ein käufer eine bestellung aufgibt, erfassen sie die transaktion in der order tabelle jede bestellung ist mit einem buyerid , der auf die buyer tabelle verweist, verbunden, um sicherzustellen, dass der käufer gültig und autorisiert ist zusätzlich zu diesem link speichern sie das orderdate , den aktuellen orderstatus , und den gesamten geldwert unter dem total feld dies gibt ihnen eine klare zusammenfassung des kaufs und unterstützt arbeitsabläufe wie bestellverfolgung und erfüllung da jede bestellung mehrere produkte enthalten kann, benötigen sie eine orderdetails tabelle, um die einzelnen positionen zu verwalten diese tabelle verbindet jeden artikel über orderid zurück zu seiner übergeordneten bestellung und mit dem gekauften produkt über productid um den zustand des kaufs genau zu erfassen, geben sie die menge und den einheitspreis zum zeitpunkt des verkaufs an die trennung der bestelldetails auf diese weise ermöglicht es ihnen, berichte zu erstellen, rechnungen zu generieren und rücksendungen oder anpassungen präzise zu bearbeiten dieses schema, mit seiner klaren trennung der anliegen und relationalen integrität, bildet eine starke grundlage für ihr e commerce system da das datenmodell nun an die realen arbeitsabläufe ihrer plattform angepasst ist, sind sie bereit, es in ihrem backend zu implementieren beginnen sie mit der einrichtung der user , käufer , und verkäufer tabellen und bauen sie von dort aus weiter einrichten von klassen im dashboard befolgen sie die folgenden schritte, um ihre entitäten in back4app zu erstellen und zu verknüpfen sie definieren klassen für benutzer , käufer , verkäufer , warenkorb , produkt , bestellung , und bestelldetails , und stellen dann zeiger her, um beziehungen wie vererbung, eins zu viele und viele zu viele darzustellen zugriff auf den datenbankbrowser öffnen sie das dashboard ihrer anwendung und erstellen sie eine neue klasse mit dem namen benutzer klicken sie auf datenbank im linken menü back4app dashboard erstellen der „benutzer“ klasse back4app erstellt automatisch eine user klasse die user klasse enthält die folgenden spalten benutzername passwort e mail usw um die benutzertyp spalte hinzuzufügen, wählen sie fügen sie eine neue spalte hinzu add new column geben sie den namen der spalte, den datentyp, den standardwert usw an add usertype column hinweis in parse enthält jede klasse ein standard objectid feld, das als primärschlüssel fungiert das bedeutet, dass objectid effektiv als userid in ihrem relationalen modell dient erstellen der „käufer“ klasse um die käuferklasse zu erstellen, kehren sie zum datenbankbrowser zurück und wählen sie klasse hinzufügen create new class wählen sie benutzerdefiniert und benennen sie es käufer add buyer class fügen sie eine zeiger spalte mit dem namen user , die auf die user klasse verweist create userid class dies simuliert die „vererbung“, indem auf die objectid des basisbenutzers verwiesen wird 3\ fügen sie die folgenden spalten hinzu versandadresse (string) zahlungsinformationen (string) wenn sie ein neues käuferobjekt erstellen, verknüpfen sie es mit einem vorhandenen benutzerdatensatz, indem sie buyer user auf die objectid dieses benutzers setzen erstellen der „verkäufer“ klasse wiederholen sie denselben prozess, um eine verkäufer klasse zu erstellen fügen sie eine zeiger spalte mit dem namen user hinzu, die auf die user klasse verweist fügen sie diese zusätzlichen spalten hinzu ladenname (string) bio (string) telefonnummer (nummer) erstellen der „produkt“ klasse wählen sie eine klasse erstellen erneut und benennen sie sie produkt fügen sie eine zeiger spalte mit dem namen verkäufer hinzu, die auf die verkäufer klasse verweist (dies erzwingt eine eins zu viele beziehung, bei der ein verkäufer viele produkte haben kann) fügen sie die folgenden spalten hinzu name (string) beschreibung (string) preis (zahl) verfügbaremenge (zahl) istaktiv (boolean) bilder (array) speichert objekte, die produktbilder darstellen erstellen der „warenkorb“ klasse klicken sie auf eine klasse erstellen , benennen sie die klasse warenkorb fügen sie eine zeiger spalte mit dem namen benutzer hinzu, die auf die benutzer klasse verweist (dies verknüpft jeden warenkorb mit einem bestimmten benutzer) fügen sie dann die folgenden spalten hinzu, um die artikel im warenkorb darzustellen artikel (array) speichert objekte, die jeden warenkorbartikel darstellen jeder artikel kann ein objekt wie { produkt zeiger auf produkt, menge zahl } sein gesamtpreis (zahl) erstellen der „bestellung“ klasse erstellen sie eine neue klasse namens order fügen sie eine pointer spalte namens buyer hinzu, die auf die buyer klasse verweist (was bedeutet, dass ein käufer viele bestellungen haben kann) fügen sie diese spalten hinzu orderdate (datum oder string, je nach vorliebe) orderstatus (string) erstellen der „orderdetails“ klasse erstellen sie schließlich eine klasse namens orderdetails fügen sie zwei pointer spalten hinzu order → verweist auf order product → verweist auf product fügen sie dann die verbleibenden spalten hinzu quantity (zahl) unitprice (zahl) dieses setup ermöglicht eine viele zu viele beziehung zwischen order und product über orderdetails , da jede bestellung mehrere produkte enthalten kann und jedes produkt in mehreren bestellungen erscheinen kann visualisierung der beziehungen hier ist ein vereinfachtes entity relationship diagramm (erd), das die klassen und ihre verweise widerspiegelt dbschema2 sobald diese klassen vorhanden sind, können sie anmeldungen und logins über die user klasse verwalten, spezialisierte käufer oder verkäuferdatensätze für verschiedene benutzertypen erstellen und produkt oder bestellinformationen mit klaren fremdschlüsselverweisen speichern durch die strukturierung ihrer datenbank auf diese weise erhalten sie ein sauberes, wartbares design für jede e commerce anwendung mit ihrem schema sind sie bereit, die authentifizierung und autorisierung einzurichten, um einzuschränken, wer produkte auflisten, bestellungen aufgeben oder administrative aufgaben durchführen kann der nächste schritt zeigt ihnen, wie sie sichere anmelde und login workflows konfigurieren, die auf den rollen und klassen basieren, die sie gerade definiert haben implementierung der authentifizierung mit back4app sichere authentifizierung ist zentral für jede e commerce plattform und hilft ihnen, benutzerkonten, zahlungsdetails und persönliche daten zu schützen back4app vereinfacht dies mit mehreren methoden – von klassischen benutzername/passwort kombinationen bis hin zu sozialen logins oder tokenbasierten workflows – und stellt sicher, dass sie ihren käufern ein einfaches, sicheres erlebnis bieten können um die authentifizierung in ihrer e commerce anwendung einzurichten, nutzen sie cloud code cloud code erweitert ihre backend funktionen, indem sie benutzerdefinierte geschäftslogik schreiben können, ohne eigene server zu hosten das bedeutet, dass sie bestellungen validieren, gebühren berechnen oder benachrichtigungen bei bestimmten ereignissen auslösen können – ganz innerhalb der infrastruktur von back4app es ist eine ideale möglichkeit, sensible transaktionen oder datenprozesse zu handhaben, die eine strenge kontrolle und schnelle ausführung erfordern um cloud code auf back4app zu aktivieren, öffnen sie das dashboard ihrer app und suchen sie den cloud code bereich find cloud code wenn sie auf cloud code , klicken, sehen sie eine main js datei, in der sie beginnen können, benutzerdefinierte funktionen zu implementieren cloud code um den authentifizierungsfluss in back4app zu implementieren, müssen sie einige funktionen in ihrem cloud code bereitstellen, um benutzer zu registrieren, benutzer anzumelden und benutzer abzumelden einen neuen benutzer registrieren (standardmäßig käufer) um einen neuen benutzer zu registrieren, verwenden sie die registrierungs methode von parse setzen sie standardfelder wie username , password , und email , und fügen sie ein benutzerdefiniertes feld hinzu, um die rolle anzugeben entweder buyer oder seller standardmäßig wird neuen benutzern die rolle buyer zugewiesen, bis sie sich entscheiden, sie zu ändern um zu beginnen, erstellen sie eine auth js datei in dem cloud verzeichnis ihres cloud codes und fügen sie den folgenden codeblock hinzu parse cloud define('signupuser', async (request) => { const { name, password, confirmpassword, email, shippingaddress, paymentinfo } = request params; // validate password match if (password !== confirmpassword) { throw new error('passwords do not match'); } const user = new parse user(); user set('username', name); user set('password', password); user set('email', email); user set('usertype', "buyer"); try { // sign up the user const signedupuser = await user signup(); console log('user registered ', signedupuser id); // create a buyer record linked to the new user const buyer = parse object extend('buyer'); const buyer = new buyer(); buyer set('user', signedupuser); buyer set('shippingaddress', shippingaddress); buyer set('paymentinfo', paymentinfo); const savedbuyer = await buyer save(); console log('buyer created ', savedbuyer id); return { success true, message 'user registered and buyer created', userid signedupuser id, buyerid savedbuyer id }; } catch (error) { console error('sign up failed ', error); throw new error('sign up failed ' + error message); } }); diese cloud funktion behandelt die benutzerregistrierung für käufer sie validiert die eingabe, erstellt einen neuen parse benutzer, weist eine rolle zu ( buyer ) und speichert käuferspezifische daten in einer separaten käuferklasse benutzer anmelden um benutzer zu authentifizieren, rufen sie die integrierte parse user login methode auf und geben sie das sitzungstoken an den client zurück fügen sie den folgenden code zu ihrer auth js datei hinzu, um diese logik in ihrem cloud code backend zu implementieren parse cloud define("loginuser", async (request) => { const { email, password } = request params; try { const user = await parse user login(email, password); // example block users with disabled flag if (user get("isdisabled")) { throw new parse error(403, "account is disabled"); } return { sessiontoken user getsessiontoken(), userid user id, }; } catch (error) { throw new parse error(101, "invalid credentials"); } }); diese funktion nimmt eine e mail und ein passwort vom client entgegen, versucht, den benutzer zu authentifizieren, und gibt das sitzungstoken zurück, wenn dies erfolgreich ist wenn das konto als deaktiviert gekennzeichnet ist, wird der zugriff blockiert und ein klarer fehler ausgegeben abmelden um die abmeldefunktion für ihr backend zu implementieren, fügen sie den folgenden codeblock in ihre auth js datei ein parse cloud define('logoutuser', async (request) => { const sessiontoken = request headers\['x parse session token']; if (!sessiontoken) { throw new error('session token required'); } const sessionquery = new parse query(' session'); sessionquery equalto('sessiontoken', sessiontoken); const session = await sessionquery first({ usemasterkey true }); if (session) { await session destroy({ usemasterkey true }); } return { success true, message 'session invalidated' }; }); dies beendet die sitzung sicher im backend und verhindert die weitere nutzung des tokens mit diesen cloud code funktionen haben sie jetzt ein sicheres authentifizierungssystem, das benutzer mit rollenbasierter logik registriert authentifiziert und autorisiert den zugriff mit sitzungstokens verknüpft benutzerkonten mit käufer spezifischen aufzeichnungen unterstützt saubere anmelde und abmeldevorgänge nutzen sie die integrierten sitzungs und e mail bestätigungstools von back4app erstellung der geschäftslogik für ihre e commerce app um benutzer, produkte, warenkörbe und transaktionen in ihrer e commerce plattform zu verwalten, definieren sie eine reihe von cloud code funktionen in back4app diese funktionen ermöglichen es ihnen, ressourcen wie verkäufer, produkte und bestellungen zu erstellen, zu lesen, zu aktualisieren und zu löschen (crud), während der sichere zugriffskontrolle, die an benutzerrollen gebunden ist, aufrechterhalten wird im folgenden finden sie eine reihe von cloud funktionen, die zeigen, wie man mit wichtigen entitäten arbeitet verkäufer , produkt , warenkorb , bestellung , und bestelldetails jede funktion behandelt einen spezifischen backend vorgang und stellt sicher, dass die berechtigungen durch benutzerüberprüfung und rollenprüfungen durchgesetzt werden verkäufer erstellen sie ein verkäuferprofil für einen benutzer, der produkte auf der plattform anbieten möchte einen verkäufer erstellen diese funktion aktualisiert die rolle des aktuellen benutzers zu verkäufer und erstellt einen seller datensatz mit informationen zum geschäft um dies in ihrem cloud code zu implementieren, erstellen sie zunächst eine seller js datei und fügen sie den folgenden codeblock hinzu parse cloud define('createseller', async (request) => { const currentuser = request user; // get the current logged in user if (!currentuser) { throw new error('user is not logged in'); } try { // check and update the user type const usertype = currentuser get('usertype'); if (usertype === 'buyer') { currentuser set('usertype', 'seller'); await currentuser save(); } // create the seller object const { businessname, bio, phone } = request params; const seller = parse object extend('seller'); const seller = new seller(); seller set('user', currentuser); seller set('storename', businessname); seller set('bio', bio); seller set('phonenumber', number(phone)); const newseller = await seller save(); console log('seller created ', newseller id); return { success true, message 'seller account created', sellerid newseller id }; } catch (error) { console error('error creating seller ', error); throw new error('error creating seller ' + error message); } }); dies stellt sicher, dass nur authentifizierte benutzer verkäufer werden können, und es verknüpft den seller datensatz mit dem entsprechenden benutzer über einen zeiger produkt produkte werden von verkäufern gelistet und können von käufern durchsucht, abgefragt und gekauft werden diese funktionen ermöglichen es verkäufern, ihre produkte zu erstellen, abzurufen, zu aktualisieren und zu löschen, und bieten käufern auch zugang zu den produkten ein produkt erstellen diese funktion fügt ein neues produkt für einen angemeldeten verkäufer hinzu und fügt bis zu drei produktbilder hinzu um dies in ihrem cloud code zu implementieren, erstellen sie eine product js datei und fügen sie den folgenden codeblock hinzu parse cloud define("addproduct", async (request) => { // destructure parameters sent from the client const { name, description, price, quantityavailable, isactive, imagefiles } = request params; // optional check if user is logged in (request user is available when an active session exists) const currentuser = request user; if (!currentuser) { throw new error("unauthorized you must be logged in to add a product "); } // ensure the user is indeed a seller by checking their usertype const usertype = currentuser get("usertype"); if (usertype != "seller") { throw new error("this user is not a seller "); } const seller = parse object extend("seller"); const query = new parse query(seller); query equalto("userid", currentuser); // match the pointer field in seller const sellerobj = await query first({ usemasterkey true }); if (!sellerobj) { throw new error("no matching 'seller' object found for this user "); } if(!array isarray(imagefiles) || imagefiles length > 3) { throw new error("a maximum of 3 images are provided"); } // create the new product object const product = parse object extend("product"); const product = new product(); product set("seller", sellerobj); // pointer to the seller product set("name", name); product set("description", description); product set("price", number(price)); product set("quantityavailable", number(quantityavailable)); product set("isactive", isactive); product set("images", imagefiles); // save the product to the database try { const savedproduct = await product save(null, { usemasterkey true }); return savedproduct; } catch (error) { throw new error(`could not create product ${error message}`); } }); diese funktion überprüft, ob der benutzer angemeldet ist und eine verkäuferrolle hat, ob ein entsprechendes seller objekt existiert und ob nicht mehr als drei bilder eingereicht werden nach der validierung speichert sie das produkt und verknüpft es mit dem verkäufer abfragen aller produkte diese funktion ruft alle produkte im system ab, die für den aufbau eines öffentlichen schaufensters verwendet werden können um dies in ihrem cloud code zu implementieren, fügen sie den folgenden codeblock in ihre products js datei ein parse cloud define("fetchallproducts", async (request) => { try { const product = parse object extend("product"); const query = new parse query(product); const products = await query find({ usemasterkey true }); // return products in a json friendly format return products map((product) => ({ id product id, sellerid product get("seller")? id, name product get("name"), description product get("description"), price product get("price"), quantityavailable product get("quantityavailable"), isactive product get("isactive"), createdat product createdat, updatedat product updatedat, })); } catch (error) { throw new error(`error fetching products ${error message}`); } }); diese funktion ruft produkte mit dem usemasterkey flag ab und formatiert sie für den frontend verbrauch abfragen eines einzelnen produkts verwenden sie diese funktion, wenn sie detaillierte produktinformationen für käufer anzeigen um dies in ihrem cloud code zu implementieren, fügen sie den folgenden codeblock in ihre products js datei ein parse cloud define("getsingleproduct", async (request) => { const { productid } = request params; const currentuser = request user; // ensure user is logged in if (!currentuser) { throw new error("you must be logged in to retrieve product information "); } if (!productid) { throw new error("missing required parameter productid "); } // query the product class const product = parse object extend("product"); const query = new parse query(product); query equalto("objectid", productid); try { const product = await query first({ usemasterkey true }); if (!product) { throw new error("product not found "); } // return a json friendly object return { objectid product id, name product get("name"), description product get("description"), price product get("price"), quantityavailable product get("quantityavailable"), isactive product get("isactive"), // optionally return more fields like images, category, etc }; } catch (error) { throw new error(`error fetching product ${error message}`); } }); diese funktion gibt vollständige produktdetails für einen artikel zurück sie überprüft, ob eine gültige productid übergeben wird und stellt sicher, dass der anforderer angemeldet ist abfragen der produkte des verkäufers diese funktion ermöglicht es einem verkäufer, alle seine eigenen produkte abzurufen um dies in ihrem cloud code zu implementieren, fügen sie den folgenden codeblock zu ihrer products js datei hinzu parse cloud define("getsellerproducts", async (request) => { const currentuser = request user; // ensure the user is logged in if (!currentuser) { throw new error("you must be logged in to fetch seller products "); } // if your schema depends on verifying the user is truly a seller, you can check usertype const usertype = currentuser get("usertype"); if (usertype !== "seller") { throw new error("only sellers can view their own products "); } // if you want to retrieve products for the currently logged in seller // fetch the seller record that points to currentuser const seller = parse object extend("seller"); const sellerquery = new parse query(seller); sellerquery equalto("user", currentuser); const sellerrecord = await sellerquery first({ usemasterkey true }); if (!sellerrecord) { throw new error("no matching seller record found for the current user "); } // finally, fetch all products pointing to this seller const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("seller", sellerrecord); productquery limit(1000); // adjust or paginate as needed try { const products = await productquery find({ usemasterkey true }); // return a more friendly json structure return products map((prod) => ({ objectid prod id, name prod get("name"), description prod get("description"), price prod get("price"), quantityavailable prod get("quantityavailable"), isactive prod get("isactive"), createdat prod createdat, updatedat prod updatedat, })); } catch (error) { throw new error(`error fetching seller products ${error message}`); } }); diese funktion bestätigt, dass der benutzer ein verkäufer ist, lokalisiert den zugehörigen seller datensatz und fragt die product klasse mithilfe eines zeigers auf den verkäufer ab verkäufer verwenden dies, um alle ihre eigenen produkte abzurufen ein produkt löschen diese funktion stellt sicher, dass nur der verkäufer, der ein produkt erstellt hat, es löschen kann um dies in ihrem cloud code zu implementieren, fügen sie den folgenden codeblock in ihre products js datei ein parse cloud define("deleteproduct", async (request) => { const { productid } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to delete a product "); } const usertype = currentuser get("usertype"); if (usertype !== "seller") { throw new error("only sellers can delete products "); } if (!productid) { throw new error("missing required parameter productid "); } // 1 find the seller record for the current user const seller = parse object extend("seller"); const sellerquery = new parse query(seller); sellerquery equalto("user", currentuser); const sellerrecord = await sellerquery first({ usemasterkey true }); if (!sellerrecord) { throw new error("no matching seller record found for the current user "); } // 2 fetch the product with a query that ensures the user owns it const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("objectid", productid); productquery equalto("seller", sellerrecord); // must match the correct seller const product = await productquery first({ usemasterkey true }); if (!product) { throw new error("product not found or you do not have permission to delete it "); } // 3 destroy the product try { await product destroy({ usemasterkey true }); return { message "product deleted successfully ", productid }; } catch (error) { throw new error(`error deleting product ${error message}`); } }); diese funktion bestätigt das eigentum des benutzers und entfernt dann das produkt aus der datenbank ein produkt aktualisieren erlauben sie verkäufern, die details eines produkts mit dieser funktion zu ändern um dies in ihrem cloud code zu implementieren, fügen sie den folgenden codeblock zu ihrer products js datei hinzu parse cloud define("updateproduct", async (request) => { const { productid, name, description, price, quantityavailable, isactive } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to update a product "); } const usertype = currentuser get("usertype"); if (usertype !== "seller") { throw new error("only sellers can update products "); } if (!productid) { throw new error("missing required parameter productid "); } // 1 find the seller record for the current user const seller = parse object extend("seller"); const sellerquery = new parse query(seller); sellerquery equalto("user", currentuser); const sellerrecord = await sellerquery first({ usemasterkey true }); if (!sellerrecord) { throw new error("no matching seller record found for the current user "); } // 2 fetch the product const product = parse object extend("product"); const query = new parse query(product); query equalto("objectid", productid); query equalto("seller", sellerrecord); // must match the seller to ensure ownership const product = await query first({ usemasterkey true }); if (!product) { throw new error("product not found or you do not have permission to modify it "); } // 3 update product fields if (name !== undefined) product set("name", name); if (description !== undefined) product set("description", description); if (price !== undefined) product set("price", price); if (quantityavailable !== undefined) product set("quantityavailable", quantityavailable); if (isactive !== undefined) product set("isactive", isactive); // 4 save changes try { const updatedproduct = await product save(null, { usemasterkey true }); return { objectid updatedproduct id, name updatedproduct get("name"), description updatedproduct get("description"), price updatedproduct get("price"), quantityavailable updatedproduct get("quantityavailable"), isactive updatedproduct get("isactive"), }; } catch (error) { throw new error(`error updating product ${error message}`); } }); es stellt sicher, dass der benutzer ein verkäufer ist, bestätigt das eigentum am produkt und aktualisiert nur die felder, die in der anfrage bereitgestellt werden warenkorb die warenkorb funktionen ermöglichen käufern, artikel zu verwalten, die sie kaufen möchten diese funktionen umfassen das hinzufügen zum warenkorb, das aktualisieren von mengen, das anzeigen des inhalts und das entfernen von artikeln zum warenkorb hinzufügen diese funktion fügt ein produkt zum warenkorb des käufers hinzu oder aktualisiert die menge, wenn es bereits vorhanden ist um dies zu implementieren, erstellen sie eine cart js datei und fügen sie den folgenden codeblock hinzu parse cloud define("addtocart", async (request) => { const { productid, quantity } = request params; // ensure there is a currently logged in user const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to modify the cart "); } if (!productid || !quantity) { throw new error("missing required parameters productid and quantity "); } // 1 fetch or create the user's cart const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", currentuser); let cart = await cartquery first({ usemasterkey true }); if (!cart) { cart = new cart(); cart set("user", currentuser); cart set("items", \[]); // initialize empty array cart set("totalprice", 0); // initialize price } // 2 fetch the product for price details (or any other attributes you need) const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("objectid", productid); const product = await productquery first({ usemasterkey true }); if (!product) { throw new error("product not found "); } const productprice = product get("price") || 0; // 3 insert or update the item in the cart const cartitems = cart get("items") || \[]; // check if this product is already in the cart const existingitemindex = cartitems findindex( (item) => item product objectid === productid ); if (existingitemindex >= 0) { // if product is already in cart, update the quantity cartitems\[existingitemindex] quantity += quantity; } else { // otherwise, add a new entry cartitems push({ product { type "pointer", classname "product", objectid productid, }, quantity quantity }); } // 4 recalculate total price // e g , summation of productprice quantity for each cart item let total = 0; for (const item of cartitems) { if (item product objectid === productid) { // use productprice from the newly fetched product total += productprice item quantity; } else { // this is a simplified approach ideally, you'd also store a price attribute on each item // or re fetch each product's price // for demonstration, we'll just skip them } } cart set("items", cartitems); cart set("totalprice", total); // 5 save the cart object try { const savedcart = await cart save(null, { usemasterkey true }); return { message "cart updated successfully", cartid savedcart id, items savedcart get("items"), totalprice savedcart get("totalprice"), }; } catch (error) { throw new error(`error saving cart ${error message}`); } }); es stellt sicher, dass der benutzer authentifiziert ist, validiert das produkt, aktualisiert die artikelliste und berechnet den gesamtpreis des warenkorbs neu abfrage des warenkorbs rufen sie den inhalt des warenkorbs des aktuellen benutzers ab, einschließlich produktdetails und zwischensummen um dies zu implementieren, fügen sie den folgenden codeblock in ihre cart js datei ein parse cloud define("getcart", async (request) => { if (!request user) throw "user must be logged in "; const user = request user; const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", user); cartquery include("items product"); // deep include const cart = await cartquery first(); if (!cart) return { items \[], totalprice 0 }; const items = cart get("items") || \[]; const parseditems = \[]; for (const item of items) { const product = item product; parseditems push({ productid product id, name product get("name"), price product get("price"), image product get("image")? url() || null, quantity item quantity, subtotal product get("price") item quantity, }); } return { cartid cart id, items parseditems, totalprice cart get("totalprice") || 0, }; }); diese funktion verwendet include("items product") um verschachtelte produktdaten in einer abfrage abzurufen warenkorb bearbeiten aktualisieren sie die menge eines artikels im warenkorb oder entfernen sie ihn vollständig, wenn die neue menge null ist um dies umzusetzen, fügen sie den folgenden codeblock in ihre cart js datei ein parse cloud define("updatecart", async (request) => { const { productid, newquantity } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to update the cart "); } if (!productid || newquantity === undefined) { throw new error("missing required parameters productid and newquantity "); } // fetch or create the user's cart const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", currentuser); let cart = await cartquery first({ usemasterkey true }); if (!cart) { // if there's no existing cart, create one cart = new cart(); cart set("user", currentuser); cart set("items", \[]); cart set("totalprice", 0); } let cartitems = cart get("items") || \[]; // find the item matching the productid const itemindex = cartitems findindex( (item) => item product id === productid ); if (itemindex === 1) { throw new error("product not found in cart please add it first "); } // if newquantity <= 0, remove the item from the cart if (newquantity <= 0) { cartitems splice(itemindex, 1); } else { // otherwise, update the quantity cartitems\[itemindex] quantity = newquantity; } // recalculate total by fetching current prices from each product let total = 0; if (cartitems length > 0) { const product = parse object extend("product"); // for each item in the cart, fetch the product to get its price for (const item of cartitems) { const productquery = new parse query(product); productquery equalto("objectid", item product objectid); const product = await productquery first({ usemasterkey true }); if (product) { const productprice = product get("price") || 0; total += productprice item quantity; } } } // update and save the cart cart set("items", cartitems); cart set("totalprice", total); try { const updatedcart = await cart save(null, { usemasterkey true }); return { message "cart updated successfully", cartid updatedcart id, items updatedcart get("items"), totalprice updatedcart get("totalprice"), }; } catch (error) { throw new error(`error updating cart ${error message}`); } }); es validiert alle produktpreise während der aktualisierung, um die totale genauigkeit sicherzustellen aus dem warenkorb löschen diese funktion entfernt ein produkt aus dem warenkorb des benutzers um dies zu implementieren, fügen sie den folgenden codeblock in ihre cart js datei ein parse cloud define("removefromcart", async (request) => { const { productid } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to remove items from the cart "); } if (!productid) { throw new error("missing required parameter productid "); } // fetch the user's cart const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", currentuser); const cart = await cartquery first({ usemasterkey true }); if (!cart) { throw new error("no existing cart found for this user "); } let cartitems = cart get("items") || \[]; // filter out the item with the specified productid const filtereditems = cartitems filter( (item) => item product id !== productid ); // if nothing changed, the product wasn't in the cart if (filtereditems length === cartitems length) { throw new error("product not found in cart "); } // recalculate the cart total let total = 0; if (filtereditems length > 0) { const product = parse object extend("product"); for (const item of filtereditems) { const productquery = new parse query(product); productquery equalto("objectid", item product objectid); const product = await productquery first({ usemasterkey true }); if (product) { const productprice = product get("price") || 0; total += productprice item quantity; } } } // update and save the cart cart set("items", filtereditems); cart set("totalprice", total); try { const updatedcart = await cart save(null, { usemasterkey true }); return { message "item removed from cart", cartid updatedcart id, items updatedcart get("items"), totalprice updatedcart get("totalprice"), }; } catch (error) { throw new error(`error removing item from cart ${error message}`); } }); es filtert das element aus dem warenkorb array und berechnet den gesamtbetrag neu, bevor es gespeichert wird bestellung diese funktionen verwalten den bestellprozess – von der erstellung von bestellungen bis zum abrufen der bestellhistorie eines verkäufers eine bestellung erstellen diese funktion wandelt den warenkorb des käufers in eine offizielle bestellung um um dies zu implementieren, erstellen sie eine order js datei und fügen sie den folgenden codeblock hinzu parse cloud define("createorder", async (request) => { const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to place an order "); } // ensure the user is a buyer (assumes buyer class with user pointer) const buyer = parse object extend("buyer"); const buyerquery = new parse query(buyer); buyerquery equalto("user", currentuser); const buyer = await buyerquery first({ usemasterkey true }); if (!buyer) { throw new error("only buyers can place orders "); } // retrieve the cart for the user const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", buyer get("user")); // assuming the user pointer is stored in buyer const cart = await cartquery first({ usemasterkey true }); if (!cart || !cart get("items") || cart get("items") length === 0) { throw new error("cart is empty"); } const items = cart get("items"); let totalamount = 0; // adjust stock and calculate total order price const orderdetails = \[]; for (const item of items) { const productid = item product id; const quantity = item quantity; const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("objectid", productid); const product = await productquery first({ usemasterkey true }); if (!product) { throw new error(`product with id ${productid} not found`); } const availablequantity = product get("quantityavailable"); if (availablequantity < quantity) { throw new error(`not enough stock for product ${product get("name")}`); } // reduce the product quantity product set("quantityavailable", availablequantity quantity); await product save(null, { usemasterkey true }); const unitprice = product get("price"); totalamount += unitprice quantity; // prepare order detail entry orderdetails push({ product, quantity, unitprice }); } // create the new order object const order = parse object extend("order"); const order = new order(); order set("buyer", buyer); // set the buyer pointer order set("total", totalamount); // set the total amount order set("orderstatus", "pending"); // set the order status order set("orderdate", new date()); // set the order date // save the order to the database try { const savedorder = await order save(null, { usemasterkey true }); // create orderdetails for each item const orderdetails = parse object extend("orderdetails"); for (const detail of orderdetails) { const orderdetail = new orderdetails(); orderdetail set("order", savedorder); orderdetail set("product", detail product); orderdetail set("quantity", detail quantity); orderdetail set("unitprice", detail unitprice); await orderdetail save(null, { usemasterkey true }); } // optionally, clear the cart after saving the order cart set("items", \[]); await cart save(null, { usemasterkey true }); return savedorder; } catch (error) { throw new error(`could not create order ${error message}`); } }); es validiert den käufer, überprüft die verfügbarkeit des bestands, reduziert den produktbestand, spart sowohl bestellung als auch bestelldetails , und leert den warenkorb nach einer erfolgreichen bestellung verkäuferbestellungen abrufen diese funktion ruft alle bestellungen ab, die produkte enthalten, die vom aktuellen verkäufer verkauft werden um dies zu implementieren, fügen sie den folgenden codeblock in ihre order js datei ein parse cloud define("getsellerorders", async (request) => { const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to view your orders "); } if (currentuser get("usertype") !== "seller") { throw new error("only sellers can access this endpoint "); } try { const seller = parse object extend("seller"); const seller = await new parse query(seller) equalto("userid", currentuser) first({ usemasterkey true }); if (!seller) { throw new error("seller profile not found "); } // find products by this seller const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("seller", seller); const products = await productquery find({ usemasterkey true }); if (!products || products length === 0) { return \[]; } // get product ids const productids = products map(product => product id); // find order details containing these products const orderdetails = parse object extend("orderdetails"); const orderdetailsquery = new parse query(orderdetails); orderdetailsquery containedin("product", products); const orderdetails = await orderdetailsquery find({ usemasterkey true }); if (!orderdetails || orderdetails length === 0) { return \[]; } const orderids = \[ new set(orderdetails map(detail => detail get("order") id))]; // query orders for these ids const order = parse object extend("order"); const orderquery = new parse query(order); orderquery containedin("objectid", orderids); orderquery include("buyer"); const orders = await orderquery find({ usemasterkey true }); // return the orders return orders map(order => ({ id order id, total order get("total"), status order get("orderstatus"), date order get("orderdate"), buyer order get("buyer") })); } catch (error) { throw new error(`could not fetch orders ${error message}`); } }); es lokalisiert produkte, die dem verkäufer gehören, fragt orderdetails für diese produkte ab, ruft die entsprechenden bestellungen ab und gibt eine vereinfachte struktur mit käuferinformationen zurück aktualisierung des bestellstatus diese funktion wechselt den status einer bestellung zwischen „ausstehend“ und „abgeschlossen “ um dies zu implementieren, fügen sie den folgenden codeblock in ihre order js datei ein parse cloud define("updateorder", async (request) => { const { orderid } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to view your orders "); } if (currentuser get("usertype") !== "seller") { throw new error("only sellers can access this endpoint "); } // validate the input parameter if (!orderid) { throw new error("missing required field orderid"); } try { // find the order with the specified orderid const order = parse object extend("order"); const query = new parse query(order); query equalto("objectid", orderid); const order = await query first({ usemasterkey true }); if (!order) { throw new error("order not found"); } // check current status // update the order status if (order get("orderstatus") === "completed") { order set("orderstatus", "pending"); } else { order set("orderstatus", "completed"); } // save the updated order await order save(null, { usemasterkey true }); return { success true, message "order status updated to completed" }; } catch (error) { throw new error(`could not update order status ${error message}`); } }); es wird sichergestellt, dass nur verkäufer diese aktion ausführen können und dass die bestellung existiert, bevor der status aktualisiert wird diese backend funktionen geben ihrer e commerce app die möglichkeit, alle kernoperationen—produktlisten, käuferwarenkörbe, bestellungen und verkäuferbestände—sicher direkt innerhalb von back4app mit cloud code zu verwalten um sicherzustellen, dass sie auf diese cloud funktionen extern zugreifen können, müssen sie alle ihre cloud code dateien in ihrer main js datei registrieren sie können dies tun, indem sie den folgenden codeblock zu ihrer main js datei hinzufügen //main js require(" /auth js") require(" /cart js") require(" /order js") require(" /product js") require(" /seller js") frontend erstellung um ihr e commerce frontend visuell zu erstellen, verwenden sie v0 dev beginnen sie damit, die seite v0 dev http //v0 dev erstellen sie ein konto, wenn sie noch keins haben sobald ihr konto eingerichtet ist, können sie mit der erstellung ihres frontends beginnen um ihr frontend zu erstellen, geben sie die folgende eingabeaufforderung ein create an e commerce web application with authentication features and a buyer and seller feature die eingabeaufforderung wird eine next js e commerce app mit den angeforderten funktionen erstellen create ecommerce app mit der vorschaufunktion können sie durch die anwendung navigieren, um zu bestätigen, dass alles wie erwartet funktioniert wenn es einige komplikationen gibt oder sie weitere funktionen hinzufügen möchten, können sie eine andere eingabeaufforderung übergeben, und v0 wird die anwendung ändern zum beispiel, übergeben sie die eingabeaufforderung the seller can create, add, delete and update products diese eingabeaufforderung wird die app ändern und seiten erstellen, auf denen der verkäufer crud operationen durchführen kann modify ecommerce app schließlich übergeben sie die eingabeaufforderung do not sort products by categories and remove the categories page and input fields, remove the second and third step from the process of becoming a seller and add a bio input field to the first step, users should only sign in with email, and enhance the seller functionality to fully support product management (crud operations) diese eingabeaufforderung wird die letzten änderungen an der anwendung vornehmen um eine vorschau der modifizierten anwendung zu erhalten, klicken sie auf die anzeigen schaltfläche im hervorgehobenen bereich im obigen bild sobald sie sicher sind, dass die anwendung das ist, was sie wollen, besteht der nächste schritt darin, das projekt auf ihr lokales gerät zu bringen um dies zu tun, klicken sie auf die schaltfläche zum herunterladen, die v0 mit der eingabeaufforderung generiert download button ein klick auf die schaltfläche zeigt ein dropdown menü mit einem link und einer download zip schaltfläche dropdown menu klicken sie als nächstes auf die download zip schaltfläche sobald sie das zip heruntergeladen haben, öffnen sie ihr terminal und erstellen sie einen neuen ordner mit dem namen ecommerce app in ihrem bevorzugten verzeichnis mkdir ecommerce app extrahieren sie nun den inhalt des zip ordners in den ecommerce app ordner navigieren sie im terminal zum ecommerce app verzeichnis und installieren sie die erforderlichen abhängigkeiten führen sie dazu den folgenden befehl aus cd ecommerce app npm install nachdem sie die abhängigkeiten installiert haben, führen sie den npm run dev befehl in ihrem terminal aus, um das projekt auf ihrem localhost server anzuzeigen integration ihres frontends mit ihrem backend um ihr frontend mit den cloud code funktionen in ihrem back4app backend zu verbinden, verwenden sie das parse javascript sdk das sdk ermöglicht es ihnen, benutzer zu authentifizieren, backend funktionen aufzurufen und sicher und effizient mit den datenmodellen ihrer app zu interagieren um das sdk einzurichten, führen sie den folgenden befehl im verzeichnis ihres projekts in ihrem terminal aus npm install parse erstellen sie dann eine lib/parse js datei, um die verbindung zu konfigurieren geben sie in dieser datei den folgenden codeblock ein import parse from "parse/dist/parse min js"; parse initialize("your app id", "your javascript key"); parse serverurl = "https //parseapi back4app com"; export default parse; ersetzen sie your app id und your javascript key mit den anmeldeinformationen, die sie in ihrem back4app dashboard unter app einstellungen diese grundlegende konfiguration stellt sicher, dass das sdk weiß, wie es mit ihrem spezifischen projekt verbinden kann jetzt, da sie ihr frontend mit ihrem backend verbunden haben, können sie beginnen, funktionen zu schreiben, um die cloud code funktionen aufzurufen, die sie in ihrer back4app anwendung definiert haben authentifizierung auf dem client dieser abschnitt zeigt, wie sie die benutzerregistrierung, das login und das logout in ihrem frontend mit dem parse sdk behandeln jede funktion entspricht einer cloud code funktion oder sdk methode, die sie in ihrem back4app backend implementiert haben in ihrer anwendung enthält das app/auth/register verzeichnis die logik zur registrierung von benutzern definieren sie im page tsx den formdata zustand dieser zustand hält die anmeldeinformationen, die zur registrierung eines benutzers erforderlich sind der formdata zustand sollte folgendermaßen aussehen const \[formdata, setformdata] = usestate({ name "", email "", password "", confirmpassword "", shippingaddress "", paymentinfo "", }); mit den anmeldedaten, die in das formdata , können sie die signupuser cloud funktion aufrufen, die sie in ihrer back4app anwendung definiert haben stellen sie sicher, dass sie parse aus der lib/parse js import parse from "@/lib/parse"; const handlesubmit = async(e react formevent) => { e preventdefault(); try { const response = await parse cloud run("signupuser", { name formdata name, email formdata email, password formdata password, confirmpassword formdata confirmpassword, shippingaddress formdata shippingaddress, paymentinfo formdata paymentinfo, }); console log("signup successful ", response); } catch (error any) { console error("signup failed ", error); } } diese funktion wird ausgeführt, wenn sie das anmeldeformular absenden sie ruft die signupuser cloud funktion auf, die im cloud code definiert ist die funktion übergibt die anmeldedaten des benutzers und spezifische daten des käufers (wie versand und zahlungsinformationen) schließlich protokolliert sie die antwort, wenn die operation erfolgreich ist, oder gibt einen fehler aus, wenn sie fehlschlägt benutzeranmeldung um einen benutzer anzumelden, verwenden sie die loginuser cloud code funktion in ihrem backend navigieren sie zum app/auth/login verzeichnis in ihrer anwendung innerhalb der page tsx datei hat v0 den zustand erstellt, der die anmeldeinformationen des benutzers enthält, die sie benötigen, um den benutzer anzumelden alles, was sie tun müssen, ist, diese anmeldeinformationen an die loginuser funktion zu übergeben zum beispiel import parse from "@/lib/parse"; const handlesubmit = async (e react formevent) => { e preventdefault(); setisloading(true); try { const result = await parse cloud run("loginuser", { email, password }); // log in using returned session token await parse user become(result sessiontoken); console log("user logged in with session ", result sessiontoken); setisloading(false); router push("/"); // proceed to app } catch (error) { console error("login failed ", error); } }; diese funktion ruft die cloud funktion loginuser , die die anmeldeinformationen des benutzers an den server sendet nach erhalt eines gültigen sitzungstokens als antwort verwendet sie parse user become um den client zu authentifizieren und die sitzung als die des angemeldeten benutzers festzulegen benutzer abmelden um einen benutzer sicher abzumelden, rufen sie sowohl parse user logout() als auch ihre benutzerdefinierte logoutuser cloud code funktion auf dies stellt sicher, dass das sitzungstoken sowohl auf dem client gelöscht als auch auf dem server ungültig gemacht wird sie finden die abmelde schaltfläche in ihrer kopfzeilenkomponente diese komponente befindet sich in ihrem components ordner im stammverzeichnis definieren sie in der komponente diese funktion const handlelogout = async () => { const sessiontoken = parse user current()? get("sessiontoken"); if (sessiontoken) { await parse user become(sessiontoken); // ensures proper context await parse cloud run("logoutuser"); // delete the session on server } await parse user logout(); // clear the local session }; diese funktion wird einen benutzer abmelden und die sitzung sowohl auf dem client als auch auf dem server löschen binden sie im jsx teil der komponente die funktion an die abmelde schaltfläche mit dem onclick ereignis zum beispiel \<dropdownmenuitem onclick={handlelogout}> logout \</dropdownmenuitem> händler onboarding dieser abschnitt zeigt eine funktion, die käufern ermöglicht, ihr konto zu upgraden und sich als verkäufer zu registrieren navigieren sie in ihrer anwendung zum app/seller/register verzeichnis in diesem verzeichnis finden sie ihre page tsx datei, in der sie die funktion definieren, die die createseller cloud funktion aufruft diese funktion ist verantwortlich für die erstellung eines verkäuferprofils für den aktuellen benutzer ändern sie in der page tsx datei den zustand formdata so, dass er wie folgt aussieht const \[formdata, setformdata] = usestate({ phone "", bio "", businessname "", }); ersetzen sie die logik in der handlesubmit funktion, die von v0 erstellt wurde, durch die folgende logik const handlesubmit = async (e react formevent) => { e preventdefault(); try { const result = await parse cloud run("createseller", { businessname formdata businessname, bio formdata bio, phone formdata phone, }); console log("seller created ", result sellerid); } catch (error) { console error("error creating seller ", error); } }; rufen sie diese funktion auf, wenn sie das formular einreichen, um ein verkäuferprofil für ihre benutzer zu erstellen produktmanagement verwenden sie diese funktionsaufrufe in ihrem frontend, um produktoperationen als verkäufer zu verwalten ein produkt erstellen um die cloud code funktion aufzurufen, die ein produkt zur datenbank hinzufügt, suchen sie das app/seller/products/new verzeichnis in diesem verzeichnis befindet sich ihre page tsx datei, in dieser datei befindet sich ein formular dieses formular nimmt die informationen für das produkt einschließlich bilder auf ändern sie den product zustand so, dass er wie folgt aussieht const \[product, setproduct] = usestate({ name "", price "", description "", stock "", status "active", }); erstellen sie auch einen zustand, um ihre bilder zu speichern const \[images, setimages] = usestate\<file\[]>(\[]); schreiben sie jetzt eine funktion, um die bilder in die datenbank hochzuladen diese funktion sollte wie folgt aussehen const handleimageupload = async (event) => { event preventdefault(); try { let name = "image jpg"; const file = new parse file(name, event target files\[0]); const photo = await file save(); setimages((prev) => \[ prev, photo]); console log("file saved ", file); alert(`image uploaded successfully`); } catch (error) { console error("error saving file ", error); } }; binden sie diese funktion an die eingabe, die für den datei upload verantwortlich ist, unter verwendung des onchange ereignisses definieren sie als nächstes die funktion handlesubmit diese funktion ruft den addproduct cloud code auf und übergibt die erforderlichen informationen so const handlesubmit = async (e react formevent) => { e preventdefault(); try { interface addproductparams { name string; description string; price number; quantityavailable number; isactive boolean; } interface addproductresponse { id string; } parse cloud run\<addproductresponse, addproductparams>("addproduct", { name product name, description product description, price product price, quantityavailable product stock, isactive product status === "active", imagefiles images, }) then((response) => { console log("product created ", response id); }); } catch (error) { console error("error creating product ", error); } }; dieser aufruf übermittelt produktdaten—einschließlich bilder—an das backend, um ein neues angebot zu erstellen alle produkte abrufen dieser aufruf ruft den gesamten katalog für öffentliche produktangebote oder einen feed der startseite ab um die funktion zu erstellen, die die fetchallproducts cloud funktion aufruft, navigieren sie zum app/products verzeichnis in der page tsx datei fügen sie diesen code hinzu interface product { id string; name string; description string; price number; image? string; } const \[products, setproducts] = usestate\<product\[]>(\[]); async function getallproducts() { try { const response = await parse cloud run("fetchallproducts"); console log("products fetched ", response); return response; } catch (error) { console error("error fetching products ", error); throw error; } } dieser obige codeblock definiert ein interface für die produkte und einen products zustand die getallproducts funktion ruft die cloud funktion fetchallproducts auf, um alle produkte in der datenbank abzurufen beachten sie, dass sie die getallproducts funktion oben innerhalb eines useeffect() hooks aufrufen müssen, um produkte beim laden der seite abzurufen und darzustellen so useeffect(() => { getallproducts() then((products) => { setproducts(products); }) catch((error) => { console error("error fetching products ", error); }); }, \[]); einzelnes produkt abrufen dieser aufruf ruft vollständige details zu einem bestimmten produkt ab navigiere zum \[id] ordner in deinem app/products verzeichnis dieser ordner enthält die page tsx datei, die die logik zum abrufen der details eines einzelnen produkts enthalten wird in der page tsx datei schreibe diesen code interface product { id string; name string; description string; price number; images? string\[]; quantityavailable number; } const \[product, setproduct] = usestate\<product>({ id "", name "", description "", price 0, images \[], quantityavailable 0, }); async function getsingleproduct() { try { const response = await parse cloud run("getsingleproduct", {productid params id}); console log("product fetched ", response); return response; } catch (error) { console error("error fetching products ", error); throw error; } } useeffect(() => { getsingleproduct() then((product) => { setproduct(product); }) catch((error) => { console error("error fetching products ", error); }); }, \[]); dieser codeblock definiert die schnittstelle für das produktobjekt und richtet eine zustandsvariable product mit standardwerten ein die getsingleproduct funktion ruft deine getsingleproduct cloud code funktion mit einer productid aus den routenparametern auf dieser useeffect hook wird einmal ausgeführt, wenn die komponente geladen wird produkt aktualisieren wenn ein verkäufer ein produkt bearbeitet, rufen sie diese funktion mit den aktualisierten feldern auf um produkte zu aktualisieren, benötigen sie ein formular mit eingabefeldern, die die neuen daten sammeln dieses formular finden sie in der page tsx datei im app/seller/products/\[id]/edit verzeichnis bevor sie ein produkt aktualisieren, müssen sie das produkt abrufen fügen sie dazu diesen code in ihre page tsx datei ein const \[product, setproduct] = usestate({ id "", name "", price "", description "", stock "", images \["", "", ""], status "active", }); useeffect(() => { async function fetchproduct() { try { const response = await parse cloud run("getsingleproduct", { productid params id, }); setproduct({ id response objectid, name response name || "", price string(response price ?? "0"), description response description || "", stock string(response quantityavailable ?? "0"), // fallback to placeholders if actual image data is not provided images \[ response image1 || `/placeholder svg?height=500\&width=500\&text=product`, response image2 || `/placeholder svg?height=500\&width=500\&text=productview+2`, response image3 || `/placeholder svg?height=500\&width=500\&text=productview+3`, ], status response isactive ? "active" "out of stock", }); } catch (error) { console error("error fetching product ", error); } } fetchproduct(); }, \[]); dieser code ruft die details eines einzelnen produkts von ihrem back4app backend mit der getsingleproduct cloud code funktion ab und speichert die details im komponentenstatus product um sie als standardwert in ihrem formular anzuzeigen, bevor sie es ändern nachdem sie die produktdetails abgerufen haben, können sie die details mit dem formular ändern nach dem ausfüllen des formulars wird das absenden des formulars eine handlesubmit funktion aufrufen, die die logik zum aktualisieren ihres produkts enthält ihre handlesubmit funktion sollte so aussehen const handlesubmit = async (e react formevent) => { e preventdefault(); try { await parse cloud run("updateproduct", { productid product id, name product name, description product description, price parsefloat(product price), quantityavailable parseint(product stock, 10), isactive product status === "active", }); } catch (error) { console error("error updating product ", error); } }; diese funktion ruft ihre updateproduct cloud code funktion auf und sendet ein objekt mit den aktualisierten produktdaten produkt löschen verwenden sie diese funktion, um ein produkt nach bestätigung des verkäufers zu löschen um ein produkt zu löschen, müssen sie eine handledelete funktion hinzufügen, die die notwendige logik zum löschen des produkts enthält sie definieren die handledelete funktion in der page tsx datei im app/seller/products/\[id]/edit verzeichnis const handledelete = async () => { const confirmdelete = confirm( "are you sure you want to delete this product? this action cannot be undone " ); if (!confirmdelete) return; try { await parse cloud run("deleteproduct", { productid product id, }); } catch (error) { console error("error deleting product ", error); } }; die handledelete funktion bestätigt zuerst die absicht des benutzers, bevor sie die deleteproduct cloud code funktion aufruft, die in ihrem backend definiert ist binden sie die handledelete funktion an die löschtaste im jsx teil der komponente zum beispiel \<button type="button" variant="destructive" onclick={handledelete} \> \<trash2 classname="h 4 w 4 mr 2" /> delete product \</button> produkte des verkäufers abrufen verwenden sie dies, um alle produkte abzurufen, die dem derzeit angemeldeten verkäufer gehören sie werden die funktion definieren, um die produkte des verkäufers im page tsx datei im app/seller/dashboard verzeichnis abzurufen schreiben sie diesen code in die datei const \[products, setproducts] = usestate< { objectid string; name string; price number; quantityavailable number; sales number; isactive boolean; }\[] \>(\[]); useeffect(() => { async function fetchproducts() { try { const result = await parse cloud run("getsellerproducts"); setproducts(result); } catch (error) { console error("error fetching products ", error); } }; fetchproducts(); }, \[]); dieser codeblock definiert den products zustand und verwendet den useeffect hook, um die fetchproducts funktion einmal beim laden aufzurufen die fetchproducts funktion ruft die getsellerproducts cloud code funktion auf und aktualisiert den products zustand mit dem ergebnis des aufrufs warenkorbverwaltung diese aufrufe ermöglichen es käufern, ihren warenkorb zu verwalten, bevor sie eine bestellung aufgeben in den warenkorb legen dieser aufruf fügt ein ausgewähltes produkt zum warenkorb des benutzers hinzu oder erhöht dessen menge suchen sie die page tsx datei im app/products verzeichnis und fügen sie die folgenden zeilen code hinzu async function handleaddtocart(productid string, quantity number = 1) { try { const response = await parse cloud run("addtocart", { productid, quantity, }); console log("add to cart success ", response); } catch (error) { console error("failed to add to cart ", error); } } die funktion handleaddtocart akzeptiert productid und optional die menge als argumente und ruft den addtocart cloud code auf ihrem backend auf diese funktion sollte ausgeführt werden, wenn ihre benutzer auf die schaltfläche "in den warenkorb legen" in ihrer produktkarte klicken zum beispiel \<button classname="w full" size="sm" onclick={() => handleaddtocart(product id)}> \<shoppingcart classname="h 4 w 4 mr 2" /> add to cart \</button> schreiben sie diesen code in die datei warenkorb anzeigen verwenden sie dies, um den inhalt des warenkorbs abzurufen und eine live zusammenfassung des warenkorbs anzuzeigen um dies zu tun, navigieren sie zur page tsx datei im app/cart verzeichnis und fügen sie den folgenden codeblock hinzu interface cartitem { id string; // product's objectid name string; price number; quantity number; image string; } const \[cartitems, setcartitems] = usestate\<cartitem\[]>(\[]); useeffect(() => { async function fetchcart() { try { const response = await parse cloud run("getcart"); const parsed = response items map((item) => ({ id item productid, name item name, price item price, quantity item quantity, image item image, })); setcartitems(parsed); } catch (error) { console error("failed to fetch cart ", error); } } fetchcart(); }, \[]); der obige codeblock definiert die struktur der warenkorbdaten im frontend mit dem interface cartitem , definiert den cartitems zustand, der die warenkorbartikel enthält er verwendet auch useeffect um die fetchcart funktion einmal beim laden der seite auszulösen die fetchcart funktion ruft die cloud code funktion getcart auf und ruft den warenkorb von ihrem backend ab es verwendet die map methode, um das backend format in das frontend format zu konvertieren, bevor die verarbeiteten warenkorbdaten im cartitems zustand gespeichert werden warenkorb element aktualisieren dieser aufruf ändert die menge eines bestimmten produkts im warenkorb in der page tsx datei im app/cart verzeichnis finden sie eine updatequantity funktion ersetzen sie diese funktion durch die folgende const updatequantity = async (productid string, newquantity number) => { if (newquantity < 1) return; try { await parse cloud run("updatecart", { productid, newquantity, }); console log("updated the cart"); } catch (error) { console error("failed to update cart item ", error); } }; diese funktion nimmt zwei parameter, productid und die aktualisierte menge, die der benutzer festlegen möchte, newquantity sie ruft ihre updatecart cloud funktion auf und sendet sowohl die productid als auch die newquantity als parameter sie binden diese funktion an die +/ tasten mit dem onclick ereignis so \<div classname="flex items center gap 2"> \<button variant="outline" size="icon" classname="h 8 w 8" onclick={() => updatequantity(item id, item quantity 1)} \> \<minus classname="h 3 w 3" /> \<span classname="sr only">decrease quantity\</span> \</button> \<span classname="w 8 text center">{item quantity}\</span> \<button variant="outline" size="icon" classname="h 8 w 8" onclick={() => updatequantity(item id, item quantity + 1)} \> \<plus classname="h 3 w 3" /> \<span classname="sr only">increase quantity\</span> \</button> \</div> aus dem warenkorb entfernen entfernt einen artikel vollständig aus dem warenkorb dazu fügen sie den folgenden codeblock in die page tsx datei im app/cart verzeichnis innerhalb dieser datei ein const removeitem = async (productid string) => { try { await parse cloud run("removefromcart", { productid, }); setcartitems((items) => items filter((item) => item id !== productid)); } catch (error) { console error("failed to remove item ", error); } }; diese funktion, removeitem , entfernt ein bestimmtes produkt aus dem warenkorb des benutzers, indem sie die cloud funktion removefromcart im backend aufruft die funktion aktualisiert auch den lokalen warenkorbstatus im frontend, um die änderung widerzuspiegeln binden sie diese funktion an die "artikel entfernen" schaltfläche, wie folgt \<button variant="ghost" size="icon" classname="h 8 w 8 text muted foreground" onclick={() => removeitem(item id)} \> \<trash2 classname="h 4 w 4" /> \<span classname="sr only">remove item\</span> \</button> bestellverwaltung diese funktionen verwalten die erstellung und verfolgung von bestellungen für käufer und verkäufer eine bestellung erstellen dies erstellt eine bestellung aus dem aktuellen inhalt des warenkorbs des benutzers sie definieren diese funktion auch in der page tsx datei im app/cart verzeichnis die funktion, die die logik zur erstellung der bestellung enthält, sollte folgendermaßen aussehen const handleorder = async () => { try { const user = parse user current(); if (!user) { throw new error("you must be logged in to place an order "); } const result = await parse cloud run("createorder"); console log("order created successfully ", result); } catch (error any) { console error("failed to create order ", error); } }; diese funktion, handleorder , verwaltet den checkout prozess, indem sie eine bestellung über ihr back4app backend aufgibt diese funktion, handleupdate , aktualisiert den status einer bestehenden bestellung, indem sie die cloud funktion namens completeorder auf deinem back4app backend aufruft binde diese funktion an einen "bearbeiten" button im jsx teil der komponente so \<button variant="ghost" size="icon" onclick={() => {handleupdate(order id)}}> \<pencil classname="h 4 w 4" /> \<span classname="sr only">view\</span> \</button> bereitstellung des frontends auf back4app containern back4app container bieten eine vereinfachte möglichkeit, deine frontend anwendung zu verpacken und bereitzustellen anstatt separate hosting dienste zu jonglieren, kannst du alle abhängigkeiten innerhalb eines docker images speichern, was eine konsistente leistung gewährleistet und die wartung vereinfacht dieser containerbasierte ansatz ist besonders nützlich für next js anwendungen, bei denen du builds für geschwindigkeit und zuverlässigkeit optimieren kannst um deine anwendung zu containerisieren, erstelle eine dockerfile um zu definieren, wie deine app gebaut und bereitgestellt wird unten ist ein beispiel dockerfile für eine next js anwendung # stage 1 build the next js app from node 20 alpine as builder workdir /app copy package json package lock json / run npm install copy run npm run build \# stage 2 run the next js app from node 20 alpine workdir /app copy from=builder /app / expose 3000 cmd \["npm", "start"] nachdem du deine dockerfile erstellt hast, erstelle eine dockerignore datei und füge diese befehle hinzu # node modules (reinstalled in docker) node modules \# next js build output next out \# logs npm debug log yarn debug log yarn error log pnpm debug log \# env files (optional — only if you handle secrets another way) env env local env development env production env test \# os / ide / editor junk ds store thumbs db vscode idea \# git git gitignore jetzt kannst du deine anwendung lokal bauen und testen um dies zu tun, führe den folgenden befehl in deinem terminal aus docker build t ecommerce app docker run p 3000 3000 ecommerce app öffnen sie http //localhost 3000 um sicherzustellen, dass ihre seite ordnungsgemäß funktioniert sobald sie überprüft haben, dass alles lokal wie erwartet funktioniert, ist es zeit, ihren code zu github zu pushen und ihn über back4app bereitzustellen stellen sie sicher, dass ihr code in ein github repository eingecheckt und gepusht wurde dies ermöglicht es back4app, auf ihr projekt zur bereitstellung zuzugreifen gehen sie in ihrem back4app konto zu ihrem dashboard und klicken sie auf das dashboard dropdown menü oben auf dem bildschirm dashboard menu wählen sie im dropdown web deployment platform web deployment platform dies bringt sie zur seite für die bereitstellung von webanwendungen deploy web application page klicken sie auf die deploy a web app schaltfläche, um den bereitstellungsprozess zu starten link github repo klicken sie dann auf import github repo und wählen sie das repository aus, das ihre dockerfile enthält geben sie ihrem projekt einen namen (z b ecommerce back4app) befolgen sie die geführte einrichtung, um ihre app zu erstellen und bereitzustellen sobald das deployment abgeschlossen ist, wird back4app eine bestätigungsseite wie diese anzeigen erfolgreiche bereitstellung der hervorgehobene bereich im obigen bild ist die url, unter der ihre anwendung live ist sie können sie verwenden, um ihre app direkt in einem webbrowser anzuzeigen und zu testen sobald das deployment abgeschlossen ist, verwenden sie das back4app dashboard, um build protokolle zu überwachen, den zustand der container zu verfolgen und bei bedarf auf frühere versionen zurückzurollen das dashboard zeigt echtzeit updates zum status der container an, was es einfacher macht, fehler zu erkennen und eine stabile umgebung für ihre benutzer aufrechtzuerhalten mit containern erhalten sie eine flexible, tragbare frontend lösung, die nahtlos mit ihrem back4app backend kombiniert wird und den weg für konsistente, problemlose releases ebnet sie können die e commerce website besuchen, die in diesem tutorial erstellt wurde hier https //ecommerceback4app mcphit37 b4a run/ fazit herzlichen glückwunsch—sie haben jetzt jede schicht eines bewährten, produktionsbereiten e commerce stacks zusammengestellt backend setup von der bereitstellung ihres back4app kontos bis zur modellierung von benutzern, produkten und bestellungen sicherheit & apis implementierung robuster authentifizierung und bereitstellung ihrer daten über rest und graphql endpunkte geschäftslogik & echtzeit updates automatisierung von workflows mit cloud code und streaming von live änderungen über livequery frontend bereitstellung einbindung des javascript sdk und bereitstellung eines next js stores in back4app containern was kommt als nächstes? tauchen sie ein in die back4app dokumentation https //www back4app com/docs und den parse platform leitfaden https //docs parseplatform org für umfassende referenzen oder treten sie dem community forum bei, um fortgeschrittene tipps und beispiel apps von betreuern und anderen entwicklern zu erhalten dieses fundament ist nur der anfang—dehnen sie es weiter aus, indem sie webhooks und geplante aufgaben integrieren, zahlungsgateways anschließen oder eine mobile begleit app erstellen halten sie an, iterieren sie, refaktorisieren sie und entwickeln sie ihren code weiter—und beobachten sie, wie ihr storefront mit ihren ambitionen wächst