Skip to main content
Google Maps API ngừng hỗ trợ vào tháng 5/2026: Danh sách kiểm
Guides

Google Maps API ngừng hỗ trợ vào tháng 5/2026: Danh sách kiểm

DirectionsService, DistanceMatrixService, Heatmap Layer và Drawing Library đều bị ngừng hỗ trợ. Danh sách kiểm tra migration hoàn chỉnh

Brent van der Heiden13 min read
#Google Maps API#API Migration#Geocoding#Routing#Developer Guide

Google đã siết chặt Maps Platform trong nhiều năm, nhưng làn sóng deprecation tháng 5/2026 là disruptive nhất từ trước đến nay. Bốn tính năng được dùng rộng rãi sẽ bị xóa khỏi Maps JavaScript API: Heatmap Layer, Drawing Library, DirectionsService và DistanceMatrixService. Nếu ứng dụng của bạn phụ thuộc vào bất kỳ cái nào trong số này, bạn chỉ còn vài tuần để migrate trước khi code ngừng hoạt động.

Đây không phải là deprecation mềm kiểu endpoint cũ vẫn tồn tại nhiều năm. Google đã đặt ngày xóa cứng, và developer console đã hiển thị cảnh báo. Bài viết này trình bày chính xác những gì đang thay đổi, lý do Google làm vậy, và cách migrate từng service với các ví dụ code hoạt động được. Nếu bạn cần thay thế trực tiếp, chúng tôi sẽ chỉ cho bạn cách MapAtlas API tương ứng với từng service Google bị deprecated.

Cái gì bị deprecated và khi nào

Timeline đầy đủ của các service bị ảnh hưởng:

ServiceDeprecatedNgày xóaThay thế (Google)
Heatmap Layer (Maps JS API)Tháng 8/2025Tháng 5/2026Maps Datasets API + deck.gl
Drawing Library (Maps JS API)Tháng 5/2025Tháng 5/2026Extended Component Library
DirectionsService (Maps JS API)25/2/2026Tháng 5/2026Routes API (REST)
DistanceMatrixService (Maps JS API)25/2/2026Tháng 5/2026Routes API (REST)

Chi tiết quan trọng: Google không xóa bỏ hoàn toàn routing và tính toán khoảng cách. Cái bị xóa là các JavaScript class phía client mà developer dùng hơn một thập kỷ, và buộc phải migrate sang Routes API mới hơn, một REST endpoint phía server. Đây không phải chỉ là nâng cấp phiên bản đơn giản. Đây là thay đổi kiến trúc di chuyển logic routing từ browser sang backend của bạn.

Cái gì sẽ bị vỡ

Nếu codebase của bạn chứa bất kỳ cái nào sau đây, nó sẽ fail sau ngày xóa:

// All of these will stop working in May 2026
const directionsService = new google.maps.DirectionsService();
const distanceMatrixService = new google.maps.DistanceMatrixService();
const heatmap = new google.maps.visualization.HeatmapLayer({ data: points });
const drawingManager = new google.maps.drawing.DrawingManager();

Sau khi xóa, các constructor này sẽ throw error. Không có fallback behavior, không có graceful degradation. Map vẫn load, nhưng bất kỳ tính năng nào phụ thuộc vào các class này sẽ bị vỡ hoàn toàn.

Tại sao Google ép buộc những thay đổi này

Lý do chính thức của Google là hiệu suất và hiện đại hóa. Routes API, thay thế cho DirectionsService và DistanceMatrixService, hỗ trợ các tính năng mới hơn như eco-friendly routing, routing cho xe hai bánh và ước tính phí cầu đường mà các class JavaScript cũ không thể đáp ứng.

Nguyên nhân thực sự là kiểm soát giá cả. Bằng cách chuyển routing sang REST API phía server, Google có billing chi tiết hơn và theo dõi usage chính xác hơn. JavaScript DirectionsService cho phép các pattern batching phía client mà Google khó đo lường chính xác. Routes API đảm bảo mọi request đều đi qua endpoint được đo lường.

Với Heatmap Layer và Drawing Library, Google đang đẩy developer sang Extended Component Library và các công cụ visualization bên thứ ba như deck.gl. Đây là một phần của pattern rộng hơn: Google giữ rendering map tile cốt lõi trong nhà và outsource phần còn lại cho ecosystem.

Tác động thực tế với developer: nhiều hạ tầng backend hơn, nhiều API key hơn cần quản lý, và trong hầu hết các trường hợp, chi phí mỗi request cao hơn ở tier giá mới.

Checklist Migration

Trước khi viết bất kỳ code migration nào, hãy đi qua checklist này:

1. Audit Codebase của bạn

Tìm kiếm các tham chiếu đến class bị deprecated trong codebase:

# Find all files using deprecated Google Maps services
grep -rn "DirectionsService\|DistanceMatrixService\|HeatmapLayer\|visualization.HeatmapLayer\|drawing.DrawingManager\|DrawingManager" \
  --include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" src/

Ghi lại mọi file và component sử dụng các service này. Ghi chú xem các call xảy ra phía client (browser) hay trong context server-rendered, ví dụ như API routes của Next.js.

2. Xác định Pattern Sử dụng

Với mỗi trường hợp sử dụng, ghi lại:

  • Travel mode được dùng (driving, walking, cycling, transit)
  • Hỗ trợ waypoint (đơn giản A-đến-B, hay multi-stop route)
  • Các field response được tiêu thụ (khoảng cách, thời gian, polyline, bước, giá vé)
  • Volume (request mỗi ngày/tháng, để ước tính chi phí)
  • Yêu cầu latency (real-time hướng tới người dùng, hay xử lý batch)

3. Chọn Target Migration

Bạn có hai lựa chọn:

Lựa chọn A: Ở lại Google. Migrate từ JavaScript class bị deprecated sang Google Routes API (REST) mới. Điều này đòi hỏi thay đổi backend, quyền API key mới và cập nhật billing.

Lựa chọn B: Chuyển provider. Migrate sang API routing bên thứ ba. Đây là thời điểm thích hợp để đánh giá các lựa chọn thay thế, vì bạn đang phải viết lại code tích hợp dù sao.

4. Thiết lập Môi trường Song song

Đừng bao giờ migrate in-place. Chạy implementation cũ và mới song song ít nhất hai tuần, so sánh kết quả về độ chính xác và latency trước khi chuyển đổi.

5. Cập nhật Xử lý Lỗi

Các service bị deprecated trả về lỗi qua callback function. Các thay thế REST API trả về HTTP status code. Logic xử lý lỗi của bạn cần thay đổi tương ứng.

Hướng dẫn Thay thế API từng Cái

DirectionsService sang MapAtlas Directions API

Trước (Google, deprecated):

const directionsService = new google.maps.DirectionsService();

directionsService.route(
  {
    origin: { lat: 52.52, lng: 13.405 },
    destination: { lat: 48.8566, lng: 2.3522 },
    travelMode: google.maps.TravelMode.DRIVING,
    waypoints: [
      { location: { lat: 50.9375, lng: 6.9603 }, stopover: true }
    ],
  },
  (result, status) => {
    if (status === "OK") {
      const route = result.routes[0];
      console.log("Distance:", route.legs[0].distance.text);
      console.log("Duration:", route.legs[0].duration.text);
    }
  }
);

Sau (MapAtlas Directions API):

const response = await fetch(
  "https://api.mapatlas.com/v1/directions?" +
    new URLSearchParams({
      origin: "52.52,13.405",
      destination: "48.8566,2.3522",
      waypoints: "50.9375,6.9603",
      mode: "driving",
      key: process.env.MAPATLAS_API_KEY!,
    })
);

const data = await response.json();

if (data.status === "OK") {
  const leg = data.routes[0].legs[0];
  console.log("Distance:", leg.distance.text);
  console.log("Duration:", leg.duration.text);
  // Polyline for map rendering
  const polyline = data.routes[0].overview_polyline;
}

Điểm khác biệt chính:

  • REST endpoint thay vì JavaScript class. Call đi từ backend, không phải browser.
  • Xác thực đơn giản hơn. Một API key trong query string hoặc header.
  • Cùng cấu trúc response. Routes, legs, distance, duration và polyline đều có đủ.

DistanceMatrixService sang MapAtlas Matrix API

Trước (Google, deprecated):

const service = new google.maps.DistanceMatrixService();

service.getDistanceMatrix(
  {
    origins: [
      { lat: 52.52, lng: 13.405 },
      { lat: 48.1351, lng: 11.582 },
    ],
    destinations: [
      { lat: 48.8566, lng: 2.3522 },
      { lat: 51.5074, lng: -0.1278 },
    ],
    travelMode: google.maps.TravelMode.DRIVING,
  },
  (response, status) => {
    if (status === "OK") {
      response.rows.forEach((row, i) => {
        row.elements.forEach((element, j) => {
          console.log(`Origin ${i} -> Dest ${j}:`,
            element.distance.text, element.duration.text);
        });
      });
    }
  }
);

Sau (MapAtlas Matrix API):

const response = await fetch("https://api.mapatlas.com/v1/matrix", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.MAPATLAS_API_KEY}`,
  },
  body: JSON.stringify({
    origins: [
      { lat: 52.52, lng: 13.405 },
      { lat: 48.1351, lng: 11.582 },
    ],
    destinations: [
      { lat: 48.8566, lng: 2.3522 },
      { lat: 51.5074, lng: -0.1278 },
    ],
    mode: "driving",
  }),
});

const data = await response.json();

data.rows.forEach((row: any, i: number) => {
  row.elements.forEach((element: any, j: number) => {
    console.log(`Origin ${i} -> Dest ${j}:`,
      element.distance.text, element.duration.text);
  });
});

Cấu trúc response gần như giống hệt nhau. Thay đổi chính là chuyển từ API browser dựa trên callback sang API server dựa trên Promise.

Thay thế Heatmap Layer

Với heatmap visualization, đường đi migration phụ thuộc vào yêu cầu của bạn:

Lựa chọn 1: MapLibre GL JS với heatmap layer (open source)

import maplibregl from "maplibre-gl";

const map = new maplibregl.Map({
  container: "map",
  style: "https://api.mapatlas.com/v1/styles/streets?key=YOUR_KEY",
  center: [13.405, 52.52],
  zoom: 10,
});

map.on("load", () => {
  map.addSource("heat-data", {
    type: "geojson",
    data: {
      type: "FeatureCollection",
      features: heatmapPoints.map((point) => ({
        type: "Feature",
        geometry: { type: "Point", coordinates: [point.lng, point.lat] },
        properties: { weight: point.weight },
      })),
    },
  });

  map.addLayer({
    id: "heatmap-layer",
    type: "heatmap",
    source: "heat-data",
    paint: {
      "heatmap-weight": ["get", "weight"],
      "heatmap-intensity": 1,
      "heatmap-radius": 20,
      "heatmap-opacity": 0.7,
    },
  });
});

Điều này cho bạn toàn quyền kiểm soát rendering heatmap và không phụ thuộc vào tile server của Google.

Lựa chọn 2: deck.gl HeatmapLayer (khuyến nghị của chính Google)

import { Deck } from "@deck.gl/core";
import { HeatmapLayer } from "@deck.gl/aggregation-layers";

const heatmapLayer = new HeatmapLayer({
  data: heatmapPoints,
  getPosition: (d) => [d.lng, d.lat],
  getWeight: (d) => d.weight,
  radiusPixels: 30,
});

Cả hai lựa chọn đều hoạt động. MapLibre GL JS tích hợp gọn gàng với tile style của MapAtlas, trong khi deck.gl có thể overlay lên bất kỳ base map nào.

So sánh Chi phí: Google Routes API vs. MapAtlas

Migrate sang Routes API của chính Google không chỉ là thay code. Nó đi kèm với mức giá mới:

ServiceGoogle (legacy, mỗi 1.000)Google Routes API (mỗi 1.000)MapAtlas (mỗi 1.000)
Directions (cơ bản)$5,00$5,00$1,50
Directions (nâng cao, waypoint/giao thông)$10,00$10,00$2,50
Distance Matrix (mỗi phần tử)$5,00$5,00$1,00
Distance Matrix (nâng cao)$10,00$10,00$2,00
Geocoding$5,00$5,00$1,50

Với 100.000 routing request mỗi tháng:

  • Google Routes API: khoảng $500-$1.000 (tùy thuộc vào tính năng sử dụng)
  • MapAtlas Directions API: khoảng $150-$250

Tiết kiệm tích lũy nhanh cho các ứng dụng kết hợp routing với geocoding và tính toán khoảng cách. Một nền tảng logistics xử lý 500.000 phần tử matrix mỗi tháng sẽ trả khoảng $2.500 ở Google so với $500 ở MapAtlas.

Xem chi tiết giá đầy đủ tại trang giá MapAtlas.

Ví dụ Code Migration Hoàn chỉnh: Trước và Sau

Đây là ví dụ migration hoàn chỉnh cho một React component hiển thị hướng lái xe trên bản đồ.

Trước: Google Maps DirectionsService trong React

import { useEffect, useRef } from "react";

function DirectionsMap({ origin, destination }: {
  origin: google.maps.LatLngLiteral;
  destination: google.maps.LatLngLiteral;
}) {
  const mapRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const map = new google.maps.Map(mapRef.current!, {
      center: origin,
      zoom: 7,
    });

    const directionsRenderer = new google.maps.DirectionsRenderer();
    directionsRenderer.setMap(map);

    const directionsService = new google.maps.DirectionsService();
    directionsService.route(
      {
        origin,
        destination,
        travelMode: google.maps.TravelMode.DRIVING,
      },
      (result, status) => {
        if (status === "OK" && result) {
          directionsRenderer.setDirections(result);
        }
      }
    );
  }, [origin, destination]);

  return <div ref={mapRef} style={{ width: "100%", height: "400px" }} />;
}

Sau: MapAtlas Directions API với MapLibre GL JS

import { useEffect, useRef } from "react";
import maplibregl from "maplibre-gl";

function DirectionsMap({ origin, destination }: {
  origin: { lat: number; lng: number };
  destination: { lat: number; lng: number };
}) {
  const mapRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const map = new maplibregl.Map({
      container: mapRef.current!,
      style: "https://api.mapatlas.com/v1/styles/streets?key=YOUR_KEY",
      center: [origin.lng, origin.lat],
      zoom: 7,
    });

    map.on("load", async () => {
      // Fetch directions from your backend (or directly if CORS allows)
      const res = await fetch(
        `/api/directions?` +
          new URLSearchParams({
            origin: `${origin.lat},${origin.lng}`,
            destination: `${destination.lat},${destination.lng}`,
            mode: "driving",
          })
      );
      const data = await res.json();

      if (data.routes?.[0]) {
        const coordinates = data.routes[0].geometry.coordinates;

        map.addSource("route", {
          type: "geojson",
          data: {
            type: "Feature",
            geometry: { type: "LineString", coordinates },
            properties: {},
          },
        });

        map.addLayer({
          id: "route-line",
          type: "line",
          source: "route",
          paint: {
            "line-color": "#4A90D9",
            "line-width": 5,
          },
        });

        // Fit map to route bounds
        const bounds = coordinates.reduce(
          (b: maplibregl.LngLatBounds, coord: [number, number]) =>
            b.extend(coord),
          new maplibregl.LngLatBounds(coordinates[0], coordinates[0])
        );
        map.fitBounds(bounds, { padding: 50 });
      }
    });

    return () => map.remove();
  }, [origin, destination]);

  return <div ref={mapRef} style={{ width: "100%", height: "400px" }} />;
}

Backend API Route (Next.js)

// app/api/directions/route.ts
import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const origin = searchParams.get("origin");
  const destination = searchParams.get("destination");
  const mode = searchParams.get("mode") || "driving";

  const response = await fetch(
    `https://api.mapatlas.com/v1/directions?` +
      new URLSearchParams({
        origin: origin!,
        destination: destination!,
        mode,
        key: process.env.MAPATLAS_API_KEY!,
      })
  );

  const data = await response.json();
  return NextResponse.json(data);
}

Pattern này giữ API key ở server và chỉ expose route geometry cho client.

Cách Kiểm tra Migration trước Deadline

Bước 1: Chạy Cả Hai API Song song

Hai tuần trước khi chuyển đổi, gọi cả service Google cũ và phần thay thế mới cho mỗi request. Log cả hai response và so sánh:

async function getDirectionsWithComparison(
  origin: string,
  destination: string
) {
  const [googleResult, mapatResult] = await Promise.all([
    fetchGoogleDirections(origin, destination),
    fetchMapAtlasDirections(origin, destination),
  ]);

  // Compare key metrics
  const distanceDelta = Math.abs(
    googleResult.distance - mapatResult.distance
  );
  const durationDelta = Math.abs(
    googleResult.duration - mapatResult.duration
  );

  console.log({
    route: `${origin} -> ${destination}`,
    googleDistance: googleResult.distance,
    mapatDistance: mapatResult.distance,
    distanceDeltaPercent: ((distanceDelta / googleResult.distance) * 100).toFixed(1),
    googleDuration: googleResult.duration,
    mapatDuration: mapatResult.duration,
    durationDeltaPercent: ((durationDelta / googleResult.duration) * 100).toFixed(1),
  });

  // Use MapAtlas result in production, Google as validation
  return mapatResult;
}

Bước 2: Cài đặt Feature Flag

Dùng feature flag để kiểm soát API nào ứng dụng của bạn gọi. Điều này cho phép rollback tức thì nếu gặp vấn đề:

const useMapAtlasDirections = process.env.FEATURE_MAPATLAS_DIRECTIONS === "true";

const directions = useMapAtlasDirections
  ? await fetchMapAtlasDirections(origin, destination)
  : await fetchGoogleDirections(origin, destination);

Bước 3: Theo dõi Tỷ lệ Lỗi

Sau khi chuyển đổi, theo dõi:

  • Tỷ lệ lỗi HTTP 4xx/5xx từ API mới
  • Tăng latency (provider mới có thể có response time khác)
  • Các field thiếu trong response mà UI của bạn phụ thuộc vào
  • Độ chính xác route cho các trường hợp edge case (tuyến phà, đường cao tốc có phí, khu vực hạn chế)

Bước 4: Load Test trước khi Go-Live

Nếu ứng dụng của bạn xử lý các spike, ví dụ như nền tảng logistics trong giờ dispatch buổi sáng, hãy load test API mới ở 2x volume đỉnh của bạn. MapAtlas cung cấp môi trường sandbox cho load testing mà không phát sinh billing production.

Timeline: Tuần này phải làm gì

Nếu bạn chưa bắt đầu migrate, đây là thứ tự ưu tiên:

  1. Tuần này: Audit codebase. Xác định mọi nơi sử dụng bốn service bị deprecated.
  2. Tuần 2: Tạo tài khoản MapAtlas và lấy API key. Free tier bao gồm 10.000 request để test.
  3. Tuần 3: Triển khai thay thế cho service quan trọng nhất của bạn, thường là DirectionsService.
  4. Tuần 4: Migrate các service còn lại và chạy kiểm thử song song.
  5. Trước deadline tháng 5: Cutover, xóa các dependency Google API, cập nhật billing.

Migration không phải lựa chọn tùy ý. Sau tháng 5/2026, các class bị deprecated sẽ bị xóa khỏi Maps JavaScript API, và bất kỳ code nào tham chiếu đến chúng sẽ throw runtime error. Bắt đầu ngay bây giờ và bạn sẽ có thời gian để test đúng cách. Đợi đến tuần cuối và bạn sẽ phải patch production dưới áp lực.

Để được hỗ trợ migration, MapAtlas cung cấp hỗ trợ developer trực tiếp. Liên hệ qua trang liên hệ hoặc bắt đầu với tài liệu API để đánh giá các API thay thế phù hợp với yêu cầu của bạn.

Câu hỏi thường gặp

Các deprecation của Google Maps API chính xác có hiệu lực khi nào?

Heatmap Layer và Drawing Library đã bị deprecated lần lượt vào tháng 8 và tháng 5/2025, với lịch xóa vào tháng 5/2026. DirectionsService và DistanceMatrixService bị deprecated ngày 25/2/2026, cũng với mục tiêu xóa vào tháng 5/2026. Sau khi xóa, các API call đến những service này sẽ trả về lỗi.

API key Google Maps JavaScript hiện tại của tôi có còn hoạt động sau tháng 5/2026 không?

API key vẫn hoạt động cho các service không bị deprecated. Tuy nhiên, bất kỳ đoạn code nào gọi DirectionsService, DistanceMatrixService, Heatmap Layer hoặc Drawing Library qua Maps JavaScript API sẽ ngừng hoạt động. Bạn cần migrate những call cụ thể đó sang API thay thế trước deadline.

Đâu là lựa chọn thay thế rẻ nhất cho Google Maps Directions API?

MapAtlas cung cấp Directions API với chi phí thấp hơn khoảng 70% so với Google. Free tier bao gồm 10.000 request mỗi tháng, đủ để phát triển và kiểm thử việc migration. Các lựa chọn khác gồm Mapbox, HERE và OpenRouteService, nhưng MapAtlas có format request/response gần nhất với Google, giúp giảm công sức migration.

Tôi có thể migrate từng phần không hay phải chuyển hết một lúc?

Bạn hoàn toàn có thể migrate từng phần. Mỗi service bị deprecated là độc lập, vì vậy bạn có thể thay DirectionsService trước, rồi DistanceMatrixService, rồi các thư viện visualization. Đây thực ra là cách được khuyến nghị vì bạn có thể kiểm thử từng phần riêng lẻ trước khi chuyển sang phần tiếp theo.

MapAtlas có hỗ trợ các waypoint và travel mode giống như Google DirectionsService không?

Có. MapAtlas Directions API hỗ trợ các mode driving, walking và cycling, cùng với các waypoint trung gian. Format request hơi khác (RESTful endpoint vs. JavaScript class) nhưng chức năng cốt lõi, routing nhiều điểm dừng với lựa chọn travel mode, là tương đương.

Thấy hữu ích? Chia sẻ nhé.

Về tác giả

Brent van der Heiden

Viết bởi

Brent van der Heiden

Co-Founder & CEO at MapAtlas

Brent built MapAtlas out of a conviction that developers deserve location APIs with fair pricing and genuine end-user privacy. He writes about geospatial infrastructure, AI search visibility, and how location data powers the products people rely on every day.

Xem tất cả bài viết
Quay lại blog