Files
History-admin/src/uhm/doc/goong_apis_in_use.md
T

14 KiB

Goong APIs In Use

Mục tiêu của tài liệu này:

  • mô tả chính xác frontend hiện tại đang dùng gì từ Goong
  • mô tả backend cần proxy gì để giấu api_key
  • mô tả response nào phải sanitize/rewrite
  • tránh liệt kê thừa các API Goong mà app hiện tại không đụng tới

Phạm vi kiểm tra:

1. Tóm tắt kỹ thuật

Frontend hiện tại không map.setStyle(goongStyleJson) trực tiếp.

Thay vào đó:

  1. app tự fetch() 2 style JSON của Goong qua backend proxy
  2. app parse style JSON để lấy:
    • raster source từ goong_satellite.json
    • sources + layers cần thiết từ goong_map_web.json
  3. nếu source dùng url, app tiếp tục fetch source manifest qua proxy trong tiles.ts
  4. app rewrite tiles[] về backend proxy rồi map.addSource(...)map.addLayer(...) thủ công
  5. từ thời điểm đó, MapLibre tự request tiếp tile/font URLs đã là URL proxy

Hệ quả:

  • nếu BE chỉ proxy assets/*.json thì chưa đủ
  • proxy phải cover style JSON, source manifest, tile URLs và glyph PBF
  • frontend hiện không nhúng api_key trong URL; backend proxy chịu trách nhiệm gọi upstream bằng key server-side nếu upstream yêu cầu

2. Luồng request thật hiện tại

2.1. App fetch style JSON qua proxy

Frontend gọi:

  1. ${API_BASE_URL}/proxy/tiles.goong.io/assets/goong_satellite.json
  2. ${API_BASE_URL}/proxy/tiles.goong.io/assets/goong_map_web.json

Upstream gốc trong code vẫn là:

  1. https://tiles.goong.io/assets/goong_satellite.json
  2. https://tiles.goong.io/assets/goong_map_web.json

Nguồn trong code:

  • GOONG_SATELLITE_STYLE_UPSTREAM_URLconfig.ts
  • GOONG_VECTOR_OVERLAY_STYLE_UPSTREAM_URLconfig.ts
  • buildGoongProxyUrl(...)config.ts
  • loadGoongStyleDocument(...)tiles.ts

Mục đích:

  • goong_satellite.json
    • app lấy ra raster source đầu tiên
    • dùng làm nền satellite
  • goong_map_web.json
    • app lấy ra các layer/source phục vụ:
      • Country Borders
      • Province Borders
      • District Borders
      • Country Labels
      • Rivers

2.2. Frontend fetch source manifests qua proxy

Khi style source có field url, tiles.ts tự fetch source manifest qua proxy trước khi gọi map.addSource(...).

Các source URL đang xuất hiện trong style JSON:

Trong goong_satellite.json

  • https://tiles.goong.io/sources/satellite.json?api_key=...
  • https://tiles.goong.io/sources/base.json?api_key=...
  • https://tiles.goong.io/sources/goong.json?api_key=...

Trong goong_map_web.json

  • https://tiles.goong.io/sources/base.json?api_key=...
  • https://tiles.goong.io/sources/goong.json?api_key=...

Ý nghĩa:

  • sources/satellite.json
    • raster source manifest cho nền satellite
  • sources/base.json
    • vector source manifest cho các lớp boundary, worldcountriespoints, worldnationalcapitals
  • sources/goong.json
    • vector source manifest cho các lớp riversandlakes, vietnam_administrator

2.3. MapLibre fetch tile URLs đã rewrite

Đây là phần dễ bị bỏ sót nhất.

Khi tiles.ts đã tải sources/satellite.json, sources/base.json, sources/goong.json, nó rewrite mọi URL trong field:

  • tiles[]

về ${API_BASE_URL}/proxy/tiles.goong.io/..., rồi mới đưa source spec cho MapLibre.

Tức là runtime thật của frontend hiện tại là:

  1. FE fetch style JSON qua proxy
  2. FE fetch source manifest qua proxy
  3. FE rewrite tiles[] về proxy
  4. MapLibre fetch tile URL đã rewrite

Nếu backend muốn che key hoàn toàn, thì backend proxy phải xử lý cả các tile URL này bằng key server-side.

3. Những upstream Goong resource đang dùng thật

Tính theo runtime hiện tại, upstream Goong đang được dùng thật là:

3.1. Style JSON

  • assets/goong_satellite.json
  • assets/goong_map_web.json

3.2. Source manifests

  • sources/satellite.json
  • sources/base.json
  • sources/goong.json

3.3. Tile endpoints bên trong source manifests

  • raster tile URLs nằm trong sources/satellite.json
  • vector tile URLs nằm trong sources/base.json
  • vector tile URLs nằm trong sources/goong.json

Lưu ý:

  • tile URL pattern chính xác phải đọc từ source manifest upstream ở runtime
  • backend không nên hardcode khi chưa xác minh nội dung tiles[]
  • frontend hiện giữ nguyên upstream target path trong proxy URL sau khi strip api_key

4. Những thứ frontend hiện tại dùng thêm hoặc KHÔNG dùng

4.1. Goong glyphs / fonts

Style JSON của Goong có field:

  • glyphs: https://tiles.goong.io/fonts/{fontstack}/{range}.pbf?api_key=...

Flow hiện tại có dùng glyphs của Goong qua proxy.

Map đang trỏ glyphs vào:

  • ${API_BASE_URL}/proxy/tiles.goong.io/fonts/{fontstack}/{range}.pbf

Nguồn trong code:

Kết luận:

  • backend proxy Goong fonts/glyphs là bắt buộc cho flow hiện tại

4.2. Goong sprite

Style JSON của Goong có:

  • sprite: https://tiles.goong.io/sprite

Nhưng flow hiện tại không phụ thuộc sprite vì:

  • app không nạp toàn bộ Goong style vào map
  • app chỉ nhặt sourceslayers
  • khi clone overlay labels, code còn chủ động loại bớt icon fields

Nguồn trong code:

Kết luận:

  • không cần backend proxy Goong sprite cho flow hiện tại

4.3. Các REST API khác của Goong

Preview search hiện có dùng trực tiếp các REST API này từ browser:

  • Place/AutoComplete
  • Place/Detail
  • Geocode reverse geocoding với latlng=lat,lng

Nguồn trong code:

Chưa dùng:

  • directions
  • distance matrix
  • static map

5. Backend cần làm gì

5.1. Mục tiêu backend

Backend phải đảm bảo:

  1. browser không gọi Goong trực tiếp
  2. browser không nhìn thấy api_key
  3. frontend vẫn nhận được dữ liệu theo format mà MapLibre/app hiện tại cần

5.2. Hai kiểu triển khai

Có 2 cách:

Cách A: Transparent proxy

BE trả về gần như đúng response của Goong, nhưng strip/sanitize mọi api_key lồng trong JSON. Frontend hiện tự wrap các upstream URL đó bằng buildGoongProxyUrl(...).

Ưu điểm:

  • gần với Goong
  • ít phải đổi frontend hơn

Nhược điểm:

  • BE phải sanitize JSON response để không lộ key trong body response

Cách B: Normalize thành API nội bộ

BE không trả nguyên style/source của Goong mà trả dữ liệu đã xử lý sẵn cho FE.

Ưu điểm:

  • hợp đồng BE-FE rõ hơn
  • ít phụ thuộc format Goong hơn

Nhược điểm:

  • cần sửa frontend nhiều hơn

Với frontend hiện tại, Cách A là hợp lý nhất.

Lưu ý quan trọng: frontend hiện mong nhận sources.*.urltiles[] ở dạng upstream URL hoặc relative URL. Không rewrite các URL này thành /proxy/... trong JSON response hiện tại, vì FE sẽ tự gọi buildGoongProxyUrl(...); rewrite sẵn sẽ dễ bị double-proxy.

6. Contract backend được khuyến nghị

6.1. Proxy style JSON

GET /proxy/tiles.goong.io/assets/goong_satellite.json

Upstream:

  • https://tiles.goong.io/assets/goong_satellite.json?api_key=<server-side-key>

Backend phải:

  • fetch upstream bằng key server-side
  • parse JSON
  • strip api_key khỏi sources.*.url, glyphs, sprite nếu các field đó xuất hiện trong body
  • giữ URL upstream/relative để frontend tự wrap bằng buildGoongProxyUrl(...)
  • có thể giữ nguyên các field khác

Response:

  • Content-Type: application/json
  • body: style JSON đã sanitize, chưa rewrite sang /proxy/...

GET /proxy/tiles.goong.io/assets/goong_map_web.json

Upstream:

  • https://tiles.goong.io/assets/goong_map_web.json?api_key=<server-side-key>

Backend phải:

  • fetch upstream bằng key server-side
  • parse JSON
  • strip api_key khỏi sources.*.url, glyphs, sprite nếu các field đó xuất hiện trong body
  • giữ URL upstream/relative để frontend tự wrap bằng buildGoongProxyUrl(...)
  • có thể giữ nguyên các field khác

Response:

  • Content-Type: application/json
  • body: style JSON đã sanitize, chưa rewrite sang /proxy/...

6.2. Proxy source manifests

GET /proxy/tiles.goong.io/sources/satellite.json

Upstream:

  • https://tiles.goong.io/sources/satellite.json?api_key=<server-side-key>

Backend phải:

  • fetch upstream
  • parse JSON
  • strip api_key khỏi mọi URL trong tiles[]
  • giữ URL upstream/relative để frontend tự wrap bằng buildGoongProxyUrl(...)
  • giữ nguyên metadata quan trọng:
    • tileSize
    • minzoom
    • maxzoom
    • bounds
    • scheme
    • attribution

Response:

  • Content-Type: application/json
  • body: source manifest đã sanitize, chưa rewrite sang /proxy/...

GET /proxy/tiles.goong.io/sources/base.json

Upstream:

  • https://tiles.goong.io/sources/base.json?api_key=<server-side-key>

Backend phải:

  • fetch upstream
  • parse JSON
  • strip api_key khỏi mọi URL trong tiles[]
  • giữ URL upstream/relative để frontend tự wrap bằng buildGoongProxyUrl(...)
  • giữ nguyên metadata tilejson khác

GET /proxy/tiles.goong.io/sources/goong.json

Upstream:

  • https://tiles.goong.io/sources/goong.json?api_key=<server-side-key>

Backend phải:

  • fetch upstream
  • parse JSON
  • strip api_key khỏi mọi URL trong tiles[]
  • giữ URL upstream/relative để frontend tự wrap bằng buildGoongProxyUrl(...)
  • giữ nguyên metadata tilejson khác

6.3. Proxy tile endpoints

Backend bắt buộc phải có route để trả tile thật.

Frontend hiện build URL proxy generic theo upstream target:

  • GET /proxy/tiles.goong.io/...

Yêu cầu:

  • request browser -> backend
  • backend -> upstream Goong bằng key server-side
  • stream response về browser
  • pass through hoặc preserve:
    • Content-Type
    • Cache-Control
    • ETag
    • Last-Modified

Response type có thể là:

  • raster image
  • vector tile protobuf

7. Runtime dependency map cho BE

7.1. Satellite background

Luồng:

  1. FE đọc goong_satellite.json
  2. FE lấy sources.satellite
  3. FE gọi sources/satellite.json qua proxy trong tiles.ts
  4. FE rewrite tiles[] về proxy URL
  5. MapLibre gọi raster tile URLs đã rewrite

BE cần cover:

  • style JSON
  • source manifest
  • raster tile URLs

7.2. Overlay borders / labels / rivers

Luồng:

  1. FE đọc goong_map_web.json
  2. FE lấy selected layers + selected sources
  3. FE gọi sources/base.json qua proxy trong tiles.ts
  4. FE gọi sources/goong.json qua proxy trong tiles.ts
  5. FE rewrite tiles[] về proxy URL
  6. MapLibre gọi vector tile URLs đã rewrite

BE cần cover:

  • style JSON
  • 2 source manifests
  • vector tile URLs tương ứng

8. Danh sách tối thiểu BE phải cover

Nếu chỉ làm đúng những gì frontend hiện tại dùng, checklist tối thiểu là:

  1. proxy tiles.goong.io/assets/goong_satellite.json
  2. proxy tiles.goong.io/assets/goong_map_web.json
  3. proxy tiles.goong.io/sources/satellite.json
  4. proxy tiles.goong.io/sources/base.json
  5. proxy tiles.goong.io/sources/goong.json
  6. proxy tiles.goong.io/fonts/{fontstack}/{range}.pbf
  7. proxy toàn bộ tile URL được khai báo trong sources/satellite.json
  8. proxy toàn bộ tile URL được khai báo trong sources/base.json
  9. proxy toàn bộ tile URL được khai báo trong sources/goong.json

9. Những gì BE chưa cần làm ngay

Cho flow hiện tại, BE chưa cần:

  • proxy Goong sprite
  • proxy geocoding / directions / autocomplete

Điều này chỉ đúng khi frontend vẫn giữ kiến trúc hiện tại.

Nếu sau này frontend chuyển sang map.setStyle(goongStyleJson) trực tiếp, hãy đánh giá lại:

  • glyphs
  • sprite

vì khi đó chúng có thể trở thành dependency bắt buộc.

10. Gợi ý ngắn cho team BE

Nếu muốn làm ít rủi ro nhất:

  1. làm proxy assets/*.json
  2. sanitize nested api_key trong style JSON
  3. làm proxy sources/*.json
  4. sanitize nested api_key trong source manifests
  5. làm proxy generic cho tile
  6. làm proxy Goong fonts/glyphs

Nếu sanitize JSON thiếu thì key có thể lộ ngay trong response style/source. Nếu proxy tile/font thiếu thì map background hoặc labels có thể không tải được.