arrow_back

Développer une API REST avec Go et Cloud Run

Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

Développer une API REST avec Go et Cloud Run

Lab 1 heure universal_currency_alt 5 crédits show_chart Intermédiaire
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

GSP761

Google Cloud – Ateliers adaptés au rythme de chacun

image

Présentation

Dans cet atelier, vous allez découvrir le scénario, puis effectuer les étapes entreprises par les personnages pour résoudre la problématique métier.

Il y a 12 ans, Lily a créé une chaîne de cliniques vétérinaires appelée Pet Theory. L'entreprise s'est beaucoup développée, et Lily passe désormais plus de temps à traiter des dossiers au téléphone avec les compagnies d'assurance qu'à s'occuper des animaux. Ce serait tellement plus simple si les compagnies d'assurance pouvaient consulter en ligne le coût total des traitements.

Lors des précédents ateliers de cette série, Ruby, la consultante en informatique et Patrick, l'ingénieur DevOps, ont transféré la base de données client de Pet Theory vers une base de données Firestore sans serveur dans le cloud, puis en ont donné l'accès aux clients afin qu'ils puissent prendre rendez-vous en ligne. L'équipe de développement de Pet Theory étant composée d'une seule personne, elle a besoin d'une solution sans serveur qui ne nécessite pas beaucoup de maintenance.

Dans cet atelier, vous allez aider Ruby et Patrick à donner aux compagnies d'assurance un accès à des données client, sans exposer d'informations personnelles. Vous allez créer une passerelle API REST (Representational State Transfer) sécurisée à l'aide de Cloud Run, qui fonctionne sans serveur. Les compagnies d'assurance pourront ainsi voir le coût total des traitements sans accéder aux informations personnelles des clients.

Prérequis

Cet atelier s'adresse aux utilisateurs de niveau intermédiaire qui maîtrisent déjà Cloud Console et les environnements Cloud Shell. Cet atelier fait partie d'une série en plusieurs parties. Il est recommandé de suivre les ateliers précédents (listés ci-dessous), mais ce n'est pas obligatoire :

  • Importer des données dans une base de données sans serveur
  • Créer une application Web sans serveur avec Firebase et Firestore
  • Créer une application sans serveur qui permet de produire des fichiers PDF

Vous devez également savoir modifier des fichiers. Vous pouvez utiliser l'éditeur de texte de votre choix (nano, vi, etc.) ou lancer l'éditeur de code de Cloud Shell, disponible dans le ruban supérieur :

cf0147b6cdd21baa.png

Préparation

Avant de cliquer sur le bouton "Démarrer l'atelier"

Lisez ces instructions. Les ateliers sont minutés, et vous ne pouvez pas les mettre en pause. Le minuteur, qui démarre lorsque vous cliquez sur Démarrer l'atelier, indique combien de temps les ressources Google Cloud resteront accessibles.

Cet atelier pratique vous permet de suivre vous-même les activités dans un véritable environnement cloud, et non dans un environnement de simulation ou de démonstration. Nous vous fournissons des identifiants temporaires pour vous connecter à Google Cloud le temps de l'atelier.

Pour réaliser cet atelier :

  • vous devez avoir accès à un navigateur Internet standard (nous vous recommandons d'utiliser Chrome) ;
Remarque : Ouvrez une fenêtre de navigateur en mode incognito/navigation privée pour effectuer cet atelier. Vous éviterez ainsi les conflits entre votre compte personnel et le temporaire étudiant, qui pourraient entraîner des frais supplémentaires facturés sur votre compte personnel.
  • vous disposez d'un temps limité ; une fois l'atelier commencé, vous ne pouvez pas le mettre en pause.
Remarque : Si vous possédez déjà votre propre compte ou projet Google Cloud, veillez à ne pas l'utiliser pour réaliser cet atelier afin d'éviter que des frais supplémentaires ne vous soient facturés.

Démarrer l'atelier et se connecter à la console Google Cloud

  1. Cliquez sur le bouton Démarrer l'atelier. Si l'atelier est payant, un pop-up s'affiche pour vous permettre de sélectionner un mode de paiement. Sur la gauche, vous trouverez le panneau Détails concernant l'atelier, qui contient les éléments suivants :

    • Le bouton Ouvrir la console Google
    • Le temps restant
    • Les identifiants temporaires que vous devez utiliser pour cet atelier
    • Des informations complémentaires vous permettant d'effectuer l'atelier
  2. Cliquez sur Ouvrir la console Google. L'atelier lance les ressources, puis ouvre la page Se connecter dans un nouvel onglet.

    Conseil : Réorganisez les onglets dans des fenêtres distinctes, placées côte à côte.

    Remarque : Si la boîte de dialogue Sélectionner un compte s'affiche, cliquez sur Utiliser un autre compte.
  3. Si nécessaire, copiez le nom d'utilisateur inclus dans le panneau Détails concernant l'atelier et collez-le dans la boîte de dialogue Se connecter. Cliquez sur Suivant.

  4. Copiez le mot de passe inclus dans le panneau Détails concernant l'atelier et collez-le dans la boîte de dialogue de bienvenue. Cliquez sur Suivant.

    Important : Vous devez utiliser les identifiants fournis dans le panneau de gauche. Ne saisissez pas vos identifiants Google Cloud Skills Boost. Remarque : Si vous utilisez votre propre compte Google Cloud pour cet atelier, des frais supplémentaires peuvent vous être facturés.
  5. Accédez aux pages suivantes :

    • Acceptez les conditions d'utilisation.
    • N'ajoutez pas d'options de récupération ni d'authentification à deux facteurs (ce compte est temporaire).
    • Ne vous inscrivez pas aux essais offerts.

Après quelques instants, la console Cloud s'ouvre dans cet onglet.

Remarque : Vous pouvez afficher le menu qui contient la liste des produits et services Google Cloud en cliquant sur le menu de navigation en haut à gauche. Icône du menu de navigation

Activer Cloud Shell

Cloud Shell est une machine virtuelle qui contient de nombreux outils pour les développeurs. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud. Cloud Shell vous permet d'accéder via une ligne de commande à vos ressources Google Cloud.

  1. Cliquez sur Activer Cloud Shell Icône Activer Cloud Shell en haut de la console Google Cloud.

Une fois connecté, vous êtes en principe authentifié et le projet est défini sur votre ID_PROJET. Le résultat contient une ligne qui déclare YOUR_PROJECT_ID (VOTRE_ID_PROJET) pour cette session :

Your Cloud Platform project in this session is set to YOUR_PROJECT_ID

gcloud est l'outil de ligne de commande pour Google Cloud. Il est préinstallé sur Cloud Shell et permet la complétion par tabulation.

  1. (Facultatif) Vous pouvez lister les noms des comptes actifs à l'aide de cette commande :
gcloud auth list
  1. Cliquez sur Autoriser.

  2. Vous devez à présent obtenir le résultat suivant :

Résultat :

ACTIVE: * ACCOUNT: student-01-xxxxxxxxxxxx@qwiklabs.net To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (Facultatif) Vous pouvez lister les ID de projet à l'aide de cette commande :
gcloud config list project

Résultat :

[core] project = <ID_Projet>

Exemple de résultat :

[core] project = qwiklabs-gcp-44776a13dea667a6 Remarque : Pour consulter la documentation complète sur gcloud, dans Google Cloud, accédez au guide de présentation de la gcloud CLI.

image

Lily, fondatrice de Pet Theory

Bonjour Ruby,

La semaine dernière, je vous ai indiqué que j'étais submergée par les dossiers et les appels téléphoniques des assureurs. Y a-t-il un moyen de leur permettre d'accéder à des données client de manière efficace et sécurisée ?

La charge de travail actuelle devient ingérable. Pouvez-vous m'aider ?

Lily

image

Ruby, consultante en logiciels

Bonjour Lily,

J'ai déjeuné avec Patrick hier, et nous avons élaboré un plan pour faciliter l'accès sécurisé de tiers autorisés aux fichiers numériques de Pet Theory.

Ce plan comprend quatre étapes :

  1. Créer une API REST simple
  2. Importer les données client de test
  3. Connecter l'API REST à la base de données client
  4. Ajouter une authentification à l'API REST

Patrick et moi avons déjà les compétences requises pour les étapes 1 et 2, c'est donc un bon point de départ. Le prototype devrait être opérationnel d'ici la fin de la semaine.

Ruby

Aidez Ruby à gérer les activités nécessaires à la création de l'API REST pour Pet Theory.

Activer les API Google

Dans ce deuxième atelier, les API ont été activées pour vous :

Nom API
Cloud Build cloudbuild.googleapis.com
Cloud Run run.googleapis.com

Développer l'API REST

  1. Activez votre projet :

gcloud config set project $(gcloud projects list --format='value(PROJECT_ID)' --filter='qwiklabs-gcp')
  1. Clonez le référentiel pet-theory et accédez au code source:

git clone https://github.com/rosera/pet-theory.git && cd pet-theory/lab08
  1. Utilisez votre éditeur de texte préféré ou utilisez le bouton Éditeur de code dans le ruban Cloud Shell pour afficher les fichiers go.mod et go.sum

  1. Créez le fichier main.go et ajoutez-y le contenu ci-dessous :

package main

import (
  "fmt"
  "log"
  "net/http"
  "os"
)

func main() {
  port := os.Getenv("PORT")
  if port == "" {
      port = "8080"
  }
  http.HandleFunc("/v1/", func(w http.ResponseWriter, r *http.Request) {
      fmt.Fprintf(w, "{status: 'running'}")
  })
  log.Println("Pets REST API listening on port", port)
  if err := http.ListenAndServe(":"+port, nil); err != nil {
      log.Fatalf("Error launching Pets REST API server: %v", err)
  }
}
  1. Créez maintenant un fichier nommé Dockerfile et ajoutez-y ce qui suit :

FROM gcr.io/distroless/base-debian10
WORKDIR /usr/src/app
COPY server .
CMD [ "/usr/src/app/server" ]

Le fichier server est le binaire d'exécution construit à partir de main.go.

  1. Exécutez la commande suivante pour créer le binaire :

go build -o server
  1. Après avoir exécuté la commande de compilation, assurez-vous que les fichiers "Dockerfile" et "server" nécessaires sont dans le même répertoire:

ls -la

(Résultat)

 .
 ├── Dockerfile
 ├── go.mod
 ├── go.sum
 ├── main.go
 └── server

Pour la plupart des applications Cloud Run basées sur Go, il est possible d'utiliser un modèle de Dockerfile comme celui présenté ci-dessus sans le modifier.

  1. Déployez votre API REST simple en exécutant la commande suivante :

gcloud builds submit \
  --tag gcr.io/$GOOGLE_CLOUD_PROJECT/rest-api:0.1

Cette commande construit un conteneur Container Registry avec votre code et le place dans votre projet. Pour voir le conteneur, cliquez sur le menu de navigation > Container Registry. Si rest-api n'apparaît pas, cliquez sur Refresh (Actualiser).

257a753ca66351a2.png

Cliquez sur Check my progress (Vérifier ma progression) pour vérifier que vous avez correctement effectué la tâche ci-dessus.

Créer une image avec Cloud Build
  1. Une fois le conteneur créé, déployez-le :

gcloud run deploy rest-api \
  --image gcr.io/$GOOGLE_CLOUD_PROJECT/rest-api:0.1 \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated \
  --max-instances=2
  1. Une fois le déploiement terminé, un message de ce type s'affiche :

Service [rest-api] revision [rest-api-00001] has been deployed and is serving
traffic at https://rest-api-[hash].a.run.app

Cliquez sur Check my progress (Vérifier ma progression) pour vérifier que vous avez correctement effectué la tâche ci-dessus.

Service API REST déployé
  1. Cliquez sur l'URL du service à la fin de ce message pour l'ouvrir dans un nouvel onglet du navigateur. Ajoutez /v1/ à la fin de l'URL, puis appuyez sur Entrée. Le message suivant doit s'afficher :

78baff71ad9313e1.png

L'API REST est opérationnelle. Avec le service de prototype disponible, dans la section suivante, l'API permettra de récupérer des informations sur le "client" à partir d'une base de données Firestore.

Importer des données client de test

image

Ruby, consultante en logiciels

Salut Patrick,

As-tu encore les pseudo-données client que nous avons créées il y a quelque temps ? Nous en aurons besoin pour les tests.

Te rappelles-tu comment configurer une base de données Firestore et importer des données ?

Ruby

image

Patrick, administrateur informatique

Bonjour Ruby,

Oui, j'ai encore les données de test. Je vais les migrer aujourd'hui vers Firestore ; tu pourras donc les utiliser pour les tests.

Patrick

Ruby et Patrick ont déjà créé une base de données de test de 10 clients contenant des propositions de traitement pour le chat d'un client.

Aidez Patrick à configurer la base de données Firestore et à importer les données de test des clients. Tout d'abord, activez Firestore dans votre projet.

  1. Revenez dans Cloud Console, puis cliquez sur le menu de navigation > Firestore.

841c521f01659814.png

  1. Cliquez sur le bouton Select Native Mode (Sélectionner le mode natif).

64b48305e0a14757.png

  1. Sélectionnez l'emplacement "nam5" (États-Unis) multirégional en haut de la liste.
  2. Cliquez sur le bouton Create Database (Créer une base de données).
  3. Attendez que la base de données soit créée.

Cliquez sur Check my progress (Vérifier ma progression) pour vérifier que vous avez correctement effectué la tâche ci-dessus.

Base de données Firestore créée
  1. Migrez les fichiers d'importation vers un bucket Cloud Storage créé à votre intention :

gsutil cp -r gs://spls/gsp645/2019-10-06T20:10:37_43617 gs://$GOOGLE_CLOUD_PROJECT-customer
  1. Importez maintenant ces données dans Firebase :

gcloud beta firestore import gs://$GOOGLE_CLOUD_PROJECT-customer/2019-10-06T20:10:37_43617/

Actualisez le navigateur Cloud Console pour afficher les résultats Firestore.

  1. Dans Firestore, cliquez sur customers (clients) sous "Root" (Racine). Vous devez voir les données des animaux importées, comme le montre la capture d'écran ci-dessous. N'hésitez pas à parcourir la base. Si vous ne voyez aucune donnée, actualisez la page.

b34f484ce74664d2.png

Beau travail ! La base de données Firestore a bien été créée et contient les données de test.

Connecter l'API REST à la base de données Firestore

image

Ruby, consultante en logiciels

Bonjour Lily,

Je voulais vous informer que Patrick et moi avons terminé les deux premières tâches de la liste.

Je vais maintenant structurer l'API REST pour qu'elle puisse accéder aux données client dans Firestore.

Ruby

image

Lily, fondatrice de Pet Theory

Bonjour Ruby,

Bravo, Ruby ! J'attends avec impatience la prochaine étape.

Lily

Dans cette section, vous allez aider Ruby à créer un autre point de terminaison dans l'API REST, qui se présentera comme suit :

https://rest-api-[hash].a.run.app/v1/customer/22530

Par exemple, cette URL doit renvoyer le montant total de tous les traitements proposés, acceptés et refusés pour le client associé à l'ID 22530, s'il existe dans la base de données Firestore :

{
  "status": "success",
  "data": {
    "proposed": 1602,
    "approved": 585,
    "rejected": 489
  }
}
Si le client n'existe pas dans la base de données, le code d'état 404 (non trouvé) et un message d'erreur sont renvoyés à la place.

Cette nouvelle fonctionnalité nécessite un package pour accéder à la base de données Firestore et un autre pour gérer le partage des ressources entre origines multiples (CORS, Cross-Origin Resource Sharing).

  1. Récupérez la valeur de la variable d'environnement $GOOGLE_CLOUD_PROJECT.
echo $GOOGLE_CLOUD_PROJECT
  1. Ouvrez le fichier main.go existant dans le répertoire "pet-theory/lab08".
Mettez à jour le contenu du fichier main.go à l'aide de la valeur affichée pour $GOOGLE_CLOUD_PROJECT.
  1. Remplacez PROJECT_ID dans le code ci-dessous :

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"

	"cloud.google.com/go/firestore"
	"github.com/gorilla/handlers"
	"github.com/gorilla/mux"
	"google.golang.org/api/iterator"
)

var client *firestore.Client

func main() {
	var err error
	ctx := context.Background()
	client, err = firestore.NewClient(ctx, "PROJECT_ID")
	if err != nil {
	log.Fatalf("Error initializing Cloud Firestore client: %v", err)
	}

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	r := mux.NewRouter()
	r.HandleFunc("/v1/", rootHandler)
	r.HandleFunc("/v1/customer/{id}", customerHandler)

	log.Println("Pets REST API listening on port", port)
	cors := handlers.CORS(
		handlers.AllowedHeaders([]string{"X-Requested-With", "Authorization", "Origin"}),
		handlers.AllowedOrigins([]string{"https://storage.googleapis.com"}),
		handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "OPTIONS", "PATCH", "CONNECT"}),
	)
	if err := http.ListenAndServe(":"+port, cors(r)); err != nil {
		log.Fatalf("Error launching Pets REST API server: %v", err)
	}
}

  1. Ajoutez l'accès au gestionnaire en bas du fichier :

func rootHandler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "{status: 'running'}")
}

func customerHandler(w http.ResponseWriter, r *http.Request) {
  id := mux.Vars(r)["id"]
  ctx := context.Background()
  customer, err := getCustomer(ctx, id)
  if err != nil {
    w.WriteHeader(http.StatusInternalServerError)
    fmt.Fprintf(w, `{"status": "fail", "data": '%s'}`, err)
    return
  }
  if customer == nil {
    w.WriteHeader(http.StatusNotFound)
    msg := fmt.Sprintf("`Customer \"%s\" not found`", id)
    fmt.Fprintf(w, fmt.Sprintf(`{"status": "fail", "data": {"title": %s}}`, msg))
    return
  }
  amount, err := getAmounts(ctx, customer)
  if err != nil {
    w.WriteHeader(http.StatusInternalServerError)
    fmt.Fprintf(w, `{"status": "fail", "data": "Unable to fetch amounts: %s"}`, err)
    return
  }
  data, err := json.Marshal(amount)
  if err != nil {
    w.WriteHeader(http.StatusInternalServerError)
    fmt.Fprintf(w, `{"status": "fail", "data": "Unable to fetch amounts: %s"}`, err)
    return
  }
  fmt.Fprintf(w, fmt.Sprintf(`{"status": "success", "data": %s}`, data))
}

  1. Ajoutez l'accès à la base de données des clients au bas du fichier :

type Customer struct {
  Email string `firestore:"email"`
  ID    string `firestore:"id"`
  Name  string `firestore:"name"`
  Phone string `firestore:"phone"`
}

func getCustomer(ctx context.Context, id string) (*Customer, error) {
  query := client.Collection("customers").Where("id", "==", id)
  iter := query.Documents(ctx)

  var c Customer
  for {
    doc, err := iter.Next()
    if err == iterator.Done {
	break
    }
    if err != nil {
	return nil, err
    }
    err = doc.DataTo(&c)
    if err != nil {
	return nil, err
    }
  }
  return &c, nil
}

func getAmounts(ctx context.Context, c *Customer) (map[string]int64, error) {
  if c == nil {
    return map[string]int64{}, fmt.Errorf("Customer should be non-nil: %v", c)
  }
  result := map[string]int64{
    "proposed": 0,
    "approved": 0,
    "rejected": 0,
  }
  query := client.Collection(fmt.Sprintf("customers/%s/treatments", c.Email))
  if query == nil {
    return map[string]int64{}, fmt.Errorf("Query is nil: %v", c)
  }
  iter := query.Documents(ctx)
  for {
    doc, err := iter.Next()
    if err == iterator.Done {
	break
    }
    if err != nil {
	return nil, err
    }
    treatment := doc.Data()
    result[treatment["status"].(string)] += treatment["cost"].(int64)
  }
  return result, nil
}

  1. Cliquez sur Save (Enregistrer) pour enregistrer le fichier.

Quiz

Quelle fonction répond aux URL ayant le format /v1/customer/ ? getAmounts customerHandler Quelle instruction renvoie un résultat positif au client ? fmt.Fprintf(w, `{"status": "fail", "data": "Unable to fetch amounts: %s"} fmt.Fprintf(w, fmt.Sprintf(`{"status": "success", "data": %s}) Quelles fonctions procèdent à la lecture dans la base de données Firestore ? customerHandler et getCustomer getCustomer et getAmounts

Déployer une nouvelle révision

  1. Recompilez le code source :

go build -o server
  1. Créez une image pour l'API REST :

gcloud builds submit \
  --tag gcr.io/$GOOGLE_CLOUD_PROJECT/rest-api:0.2
  1. Déployez la nouvelle image :

gcloud run deploy rest-api \
  --image gcr.io/$GOOGLE_CLOUD_PROJECT/rest-api:0.2 \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated \
  --max-instances=2

Cliquez sur Check my progress (Vérifier ma progression) pour vérifier que vous avez correctement effectué la tâche ci-dessus.

Révision de l'image 0.2
  1. Une fois le déploiement terminé, un message semblable au précédent s'affiche. L'URL de l'API REST n'a pas changé lorsque vous avez déployé la nouvelle version :

Service [rest-api] revision [rest-api-00002] has been deployed and is serving
traffic at https://rest-api-[hash].a.run.app
  1. Revenez dans l'onglet du navigateur qui pointe déjà vers cette URL (avec /v1 à la fin). Actualisez la page et vérifiez que le même message s'affiche, ce qui indique que l'API est toujours en cours d'exécution.

status-message.png

  1. Ajoutez /customer/22530 à l'URL de l'application dans la barre d'adresse de votre navigateur. Vous devez obtenir cette réponse JSON qui affiche la somme totale des traitements proposés, acceptés et refusés pour ce client :

b3009606f951bfab.png

Voici quelques ID client supplémentaires que vous pouvez indiquer dans l'URL au lieu de 22530 :

  • 34216
  • 70156 (tous les montants doivent être nuls)
  • 12345 (le client/l'animal n'existe pas, un message d'erreur tel que Query is nil [La requête est nulle] devrait s'afficher).

Vous avez créé une API REST évolutive, sans serveur, qui nécessite peu de maintenance et qui effectue des lectures à partir d'une base de données.

Félicitations !

Ruby et Patrick ont réussi à créer un prototype d'API REST pour Pet Theory.

Pet_theory_125.png

Terminer votre quête

Cet atelier d'auto-formation fait partie de la quête Qwiklabs Google Cloud Run Serverless Workshop. Une quête est une série d'ateliers associés qui constituent un parcours de formation. Si vous terminez cette quête, vous obtiendrez le badge ci-dessus attestant de votre réussite. Vous pouvez rendre publics les badges que vous recevez et ajouter leur lien dans votre CV en ligne ou sur vos comptes de réseaux sociaux. Inscrivez-vous à cette quête pour obtenir immédiatement les crédits associés à cet atelier si vous l'avez suivi. Découvrez les autres quêtes Qwiklabs disponibles.

Atelier suivant

Poursuivez votre quête avec le prochain atelier de la série, Créer des PDF avec Go et Cloud Run.

Terminer l'atelier

Une fois l'atelier terminé, cliquez sur Terminer l'atelier. Votre compte et les ressources utilisées sont alors supprimés de la plate-forme d'atelier.

Si vous le souhaitez, vous pouvez noter l'atelier. Sélectionnez un nombre d'étoiles, saisissez un commentaire, puis cliquez sur Envoyer.

Voici à quoi correspond le nombre d'étoiles que vous pouvez attribuer à un atelier :

  • 1 étoile = très insatisfait(e)
  • 2 étoiles = insatisfait(e)
  • 3 étoiles = ni insatisfait(e), ni satisfait(e)
  • 4 étoiles = satisfait(e)
  • 5 étoiles = très satisfait(e)

Si vous ne souhaitez pas donner votre avis, vous pouvez fermer la boîte de dialogue.

Pour soumettre des commentaires, suggestions ou corrections, veuillez accéder à l'onglet Assistance.

Dernière mise à jour du manuel : 11 août 2021
Dernier test de l'atelier : 11 août 2021

Copyright 2024 Google LLC Tous droits réservés. Google et le logo Google sont des marques de Google LLC. Tous les autres noms d'entreprises et de produits peuvent être des marques des entreprises auxquelles ils sont associés.