Skip to content
Learni
Voir tous les tutoriels
Google Cloud

Comment déployer une API scalable sur App Engine en 2026

Read in English

Introduction

Google App Engine est une PaaS serverless qui gère l'infrastructure pour vous, idéale pour des APIs scalables sans ops. En 2026, avec l'environnement standard optimisé pour les workloads légers et flexible pour les customs, elle excelle en auto-scaling, zero-downtime deployments et intégration GCP native.

Ce tutoriel expert vous guide pas à pas pour déployer une API Node.js complète : routes sécurisées, intégration Firestore, queues tasks et monitoring. Pourquoi c'est crucial ? App Engine scale de 0 à des millions de req/s sans config manuelle, réduit les coûts via cold starts optimisés et intègre seamlessly avec Cloud Run pour hybrid.

On part d'un projet vide vers un setup prod : app.yaml avancé, versioning, traffic splitting. À la fin, votre API sera résiliente, observable et SEO-optimisée pour Learni Dev. Temps estimé : 30 min pour un deploy live. (128 mots)

Prérequis

  • Compte Google Cloud Platform activé (facturation requise, quota App Engine standard)
  • gcloud CLI installée et authentifiée (gcloud auth login)
  • Node.js 20+ et npm/yarn
  • Projet GCP existant (gcloud config set project MON_PROJET)
  • Connaissances avancées en Node.js/Express et YAML

Initialiser le projet Node.js

terminal
mkdir api-app-engine
cd api-app-engine
npm init -y
npm install express @google-cloud/firestore cors helmet morgan
npm install --save-dev typescript @types/node @types/express @types/cors @types/helmet @types/morgan ts-node nodemon
npx tsc --init

Cette commande crée un projet Node.js avec Express pour l'API, Firestore pour la DB serverless, et sécurité (cors, helmet). Les dev deps activent TypeScript pour du code type-safe. Piège : oubliez gcloud app create si premier deploy dans le projet.

Configurer package.json pour prod

Adaptez package.json pour un démarrage optimisé en prod. Ajoutez des scripts pour local (npm run dev) et prod (npm start). Spécifiez engines.node pour matcher App Engine (Node 20+). Cela évite les cold starts lents.

package.json complet

package.json
{
  "name": "api-app-engine",
  "version": "1.0.0",
  "description": "API scalable sur App Engine",
  "main": "dist/server.js",
  "scripts": {
    "build": "tsc",
    "start": "node dist/server.js",
    "dev": "nodemon --exec ts-node server.ts"
  },
  "engines": {
    "node": "20.x"
  },
  "dependencies": {
    "express": "^4.19.2",
    "@google-cloud/firestore": "^7.7.0",
    "cors": "^2.8.5",
    "helmet": "^7.1.0",
    "morgan": "^1.10.0"
  },
  "devDependencies": {
    "@types/node": "^22.5.5",
    "@types/express": "^4.17.21",
    "@types/cors": "^2.8.17",
    "@types/helmet": "^4.0.0",
    "@types/morgan": "^1.9.9",
    "typescript": "^5.6.2",
    "ts-node": "^10.9.2",
    "nodemon": "^3.1.7"
  }
}

Ce package.json est prod-ready : build TS vers JS, engines lock Node version pour App Engine. Scripts isolent dev/prod. Piège : sans engines, App Engine peut downgrader Node et casser des deps.

Serveur Express avec Firestore

server.ts
import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import morgan from 'morgan';
import { Firestore, FieldValue } from '@google-cloud/firestore';

const app = express();
const PORT = process.env.PORT || 8080;
const firestore = new Firestore();

app.use(helmet());
app.use(cors({ origin: '*' }));
app.use(morgan('combined'));
app.use(express.json());

app.get('/health', (req, res) => res.status(200).json({ status: 'OK' }));

app.post('/items', async (req, res) => {
  try {
    const { name } = req.body;
    if (!name) return res.status(400).json({ error: 'Name required' });
    const docRef = firestore.collection('items').doc();
    await docRef.set({ name, created: FieldValue.serverTimestamp() });
    res.status(201).json({ id: docRef.id });
  } catch (error) {
    res.status(500).json({ error: 'Internal error' });
  }
});

app.get('/items/:id', async (req, res) => {
  try {
    const doc = await firestore.collection('items').doc(req.params.id).get();
    if (!doc.exists) return res.status(404).json({ error: 'Not found' });
    res.json(doc.data());
  } catch (error) {
    res.status(500).json({ error: 'Internal error' });
  }
});

app.listen(PORT, () => {
  console.log(`Server on port ${PORT}`);
});

Serveur TS complet avec routes CRUD Firestore, sécurité helmet/cors, logging morgan. Utilise process.env.PORT obligatoire pour App Engine. Piège : sans try/catch async, les erreurs crashent l'instance ; toujours logger en prod.

Compiler et tester localement

Exécutez npm run build puis npm start pour tester. Vérifiez /health, POST /items et GET /items/:id avec curl ou Postman. Analogie : comme un avion avant décollage, testez cold starts (kill puis relancez).

app.yaml pour standard environment

app.yaml
runtime: nodejs20
env: standard

env_variables:
  NODE_ENV: "production"
  GOOGLE_CLOUD_PROJECT: "votre-projet-id"

automatic_scaling:
  min_instances: 1
  max_instances: 100
  target_cpu_utilization: 0.65
  max_concurrent_requests: 100

handlers:
- url: /.*
  script: auto
  secure: always
  redirect_http_response_code: 301

liveness_check:
  path: "/health"
  check_interval: 30s
  timeout: 5s
  failure_threshold: 3
  success_threshold: 2

readiness_check:
  path: "/health"
  check_interval: 10s
  timeout: 3s
  failure_threshold: 3
  success_threshold: 2

app.yaml configure runtime Node20, scaling auto (1-100 instances, CPU 65%), health checks pour zero-downtime. Secure HTTPS only. Piège : sans min_instances:1, cold starts >1s latence ; ajustez pour votre trafic.

Premier déploiement

Créez l'app si besoin : gcloud app create --region=us-central. Puis gcloud app deploy. Accédez via gcloud app browse. Vérifiez logs : gcloud app logs tail -s default.

Script de déploiement automatisé

deploy.sh
#!/bin/bash
PROJET="votre-projet-id"
VERSION="v1-$(date +%Y%m%d-%H%M%S)"

gcloud config set project $PROJET
git add .
git commit -m "Deploy $VERSION"
npm run build
gcloud app deploy --version=$VERSION --project=$PROJET

gcloud app services default versions list

gcloud app traffic default allocate --version=$VERSION --split=100

Script bash pour build, deploy avec timestamp version, et route 100% traffic. Intégrez Git pour CI/CD. Piège : sans --version, overwrite crash traffic ; toujours nouvelle version pour rollback.

Traffic splitting multi-versions

terminal
gcloud app versions list --service=default

gcloud app traffic default allocate \
  --split=v1=80 \
  --split=v2=20

# Rollback
gcloud app traffic default shift v1 --version=v1

Split 80/20 pour A/B testing sans downtime. shift migre progressivement. Piège : splits >2 versions fragmentent metrics ; limitez à 2-3 pour prod.

Intégration queues pour tâches async

Pour workloads lourds (ex: emails), ajoutez à app.yaml :

``yaml
dispatch:
- url: "/tasks/"
module: "default"

queue:
default:
rate: "100/m"
bucket_size: 10
`
Envoi :
taskqueue.add(url='/tasks/process', payload=data)`.

.gcloudignore pour optimiser deploy

.gcloudignore
node_modules
npm-debug.log
.DS_Store
*.log
.nyc_output
coverage
.env
.nyc_output
.cache
*.tsbuildinfo
dist

Ignore node_modules (rebuild en env), logs, cache pour deploys <10s. Réduit bande passante 90%. Piège : oublier = deploys lents, timeouts.

Bonnes pratiques

  • Scaling finetuning : Monitor CPU/RAM via Cloud Monitoring, ajustez target_cpu_utilization à 60-70% pour équilibre coût/perf.
  • Secrets management : Utilisez Secret Manager pour API keys (gcloud secrets versions access), injectez via env_vars runtime config.
  • Observability : Activez Cloud Trace/Profiler ; structurez logs JSON pour BigQuery export.
  • Migrez vers flexible si custom deps : env: flex, dockerfile avec gcr.io.
  • Cost control : Set max_instances bas, utilisez F1 instances pour dev.

Erreurs courantes à éviter

  • Port fixe : Toujours process.env.PORT, App Engine force 8080.
  • Cold starts ignorés : Ajoutez min_instances:1 pour prod ; testez avec gcloud app instances delete.
  • Versions sans split : Deploy direct overwrite downtime ; toujours --version + allocate.
  • Firestore sans index : Composite queries échouent ; créez via console ou firestore.indexes.json.

Pour aller plus loin

Découvrez nos formations Learni sur Google Cloud pour maîtriser Serverless et DevOps.