FDE PulseViệc làm FDE đang mở 316Mới đăng 7 ngày qua 10Chủ đề nổi bật: Đào tạo kỹ năng FDE tại Đông Nam Á

Tờ báo của nghề Forward Deployed Engineer

Bách khoa

Gặp SOAP, gRPC hay GraphQL ở khách: gọi được lệnh đầu tiên trong một ngày

Ngày đầu ở khách hiếm khi có một REST API gọn gàng: thường là một service XML từ thời trước, một file .proto hoặc một endpoint GraphQL duy nhất. Muốn gọi được, hãy xin đúng bản hợp đồng thay vì đọc hết tài liệu.

Đồ hoạTừ API lạ đến lời gọi chạy được trong một ngày
  1. 1Nhận diện giao thứcHỏi khách hệ thống dùng SOAP, gRPC hay GraphQL
  2. 2Xin bản hợp đồngWSDL cho SOAP, file .proto cho gRPC, schema cho GraphQL
  3. 3Gọi lệnh dễ nhấtMột operation chỉ đọc, một unary RPC, một query vài field
  4. 4Thử lỗi có chủ đíchGửi request sai để xem Fault hoặc lỗi trả về trông thế nào
  5. 5Bọc thành hàmMột hàm có timeout hoặc deadline, trả lỗi thống nhất cho cả đội

Giao thức nào cũng vậy: xin hợp đồng, gọi lệnh dễ nhất, rồi bọc lại với timeout và xử lý lỗi.

Đồ hoạ: FDE Times

Tóm tắt nhanh

  • Với SOAP, gRPC hay GraphQL, việc đầu tiên luôn là xin bản hợp đồng: WSDL, .proto hoặc schema.
  • Lời gọi đầu tiên nên là lời gọi đơn giản nhất: một operation, một unary RPC, một query vài field.
  • Thành quả cuối ngày là một hàm có timeout và báo lỗi rõ ràng, không phải một đoạn script chỉ chạy được một lần.
Chia sẻLinkedInFacebookX

Chín giờ sáng ngày đầu ở khách, bạn hỏi xin API của hệ thống đơn hàng. Câu trả lời có thể là “bên em dùng SOAP”, “có service gRPC nội bộ” hoặc “cứ gọi vào /graphql”.

Nếu bạn chỉ quen REST, một phong cách kiến trúc stateless mà mỗi request tự mang đủ thông tin để server hiểu và xử lý, thì cả ba nghe như ba tuần đọc tài liệu.

Thực tế không đến mức ấy. Cả ba giao thức đều dựa trên một bản hợp đồng có cấu trúc chặt, và chính bản hợp đồng đó là đường tắt. Ai xin đúng file và gọi đúng lệnh dễ nhất thì có thể gọi thành công ngay trong ngày.

Với một FDE, đây là kỹ năng nên luyện trước khi ra khách. Gọi được hệ thống của khách càng sớm, bạn càng sớm có dữ liệu thật để làm việc thay vì ngồi chờ.

Cuối ngày bạn cần cầm được gì?

Mục tiêu là một “thẻ tích hợp” dài một trang cho mỗi hệ thống. Thẻ ghi giao thức, file hợp đồng, một lời gọi mẫu chạy được, timeout đã chọn và lỗi trông như thế nào. Kèm theo là một hàm nhỏ trong code của bạn để cả đội gọi lại.

Chuẩn bị trước không nhiều: quyền truy cập mạng tới môi trường test của khách, thông tin xác thực, và một ngôn ngữ bạn viết nhanh. Riêng gRPC cho phép client và server viết bằng các ngôn ngữ khác nhau, miễn là ngôn ngữ đó được gRPC hỗ trợ. Server của khách viết bằng gì cũng không bắt bạn đổi stack.

Bảng dưới gom lại những gì cần làm với từng giao thức. Cột cuối là gợi ý thực hành: với giao thức nào cũng vậy, hãy cố tình gọi sai một lần để tận mắt thấy lỗi trả về trông thế nào trước khi viết code xử lý.

Giao thức Hợp đồng cần xin Lời gọi đầu tiên nên chọn Cần quan sát khi thử lỗi
SOAP File WSDL Một operation chỉ đọc, ít tham số Phần tử Fault trong body
gRPC File .proto Một unary RPC Gọi sai một lần, ghi lại lỗi client trả về
GraphQL Schema (hệ thống type) Một query lấy hai, ba field Gửi query sai, ghi lại response nhận được

Bước 1: đừng hỏi “API ở đâu”, hãy hỏi “hợp đồng ở đâu”

Câu hỏi đầu tiên quyết định cả ngày. Với SOAP, theo SmartBear, service phải có một file WSDL định nghĩa mọi operation cùng input và output. Với gRPC, Protocol Buffers vừa là định dạng tuần tự hóa vừa là ngôn ngữ mô tả giao diện (IDL), nên file .proto chính là hợp đồng.

GraphQL hơi khác: API được tổ chức quanh type và field chứ không quanh endpoint. Mọi service GraphQL đều định nghĩa một hệ thống type, và công cụ có thể dùng nó để kiểm tra cú pháp query trước khi chạy. Thứ bạn cần xin là schema, cộng với địa chỉ endpoint.

Kiểm tra sau bước này: bạn có file hợp đồng trong tay và tìm được trong đó ít nhất một thao tác chỉ đọc. Nếu khách gửi một file PDF hướng dẫn thay vì WSDL hay .proto, hãy hỏi lại. PDF dễ bị cũ, còn file hợp đồng là thứ hệ thống thật đang dùng.

Bước 2: SOAP, đọc phong bì trước khi đọc thư

SOAP là giao thức có chuẩn và cấu trúc chặt, thông điệp viết bằng XML. Theo bản Primer SOAP 1.2 của W3C, mỗi thông điệp nằm trong một envelope và body là phần bắt buộc trong envelope đó; lỗi được báo qua phần tử Fault. Bộ khung trông như sau (minh họa giản lược, namespace và tên operation phải lấy từ WSDL của khách):

<env:Envelope xmlns:env="(namespace theo phiên bản SOAP của khách)">
  <env:Body>
    <GetOrder>
      <OrderId>A-1024</OrderId>
    </GetOrder>
  </env:Body>
</env:Envelope>

Trong WSDL, chọn operation có ít tham số nhất và chỉ đọc dữ liệu. Gửi một mã đơn hàng có thật trên môi trường test để nhận về dữ liệu thật.

Kiểm tra: response có envelope, body chứa dữ liệu. Sau đó cố tình gửi một mã sai để xem Fault trông thế nào và ghi mẫu đó vào thẻ tích hợp. Code xử lý lỗi sau này sẽ cần đúng cấu trúc đó.

Bước 3: gRPC, bắt đầu từ unary, để streaming lại sau

Theo tài liệu gRPC, client có thể gọi trực tiếp một method trên server ở máy khác như gọi hàm cục bộ. gRPC có bốn kiểu method. Kiểu đơn giản nhất là unary: client gửi một request, nhận lại một response. Đây là lời gọi đầu tiên bạn nên làm.

Mở file .proto, tìm dòng rpc có request và response đều không có từ khóa stream. Đoạn dưới là ví dụ giả định để bạn nhận dạng:

// minh họa giản lược, tên service và message là giả định
service OrderService {
  rpc GetOrder (GetOrderRequest) returns (Order);              // unary: gọi cái này trước
  rpc WatchOrders (stream Filter) returns (stream OrderEvent);  // để sau
}

Kiểu bidirectional streaming, khi cả hai bên cùng gửi một chuỗi message qua một stream đọc-ghi, là phần khó. Nó không cần cho ngày đầu tiên.

Từ file .proto, sinh code client cho ngôn ngữ của bạn rồi mở một channel. Theo gRPC, channel là kết nối tới server tại một host và port cụ thể. Thông tin riêng của từng lời gọi, như header xác thực, đi qua metadata.

Kiểm tra: lời gọi unary trả về một object đúng kiểu Order. Nếu bị từ chối, hãy xem lại metadata xác thực trước khi nghi ngờ code.

Bước 4: GraphQL, chỉ xin đúng thứ bạn cần

GraphQL vừa là ngôn ngữ truy vấn cho API vừa là runtime phía server. Vì API xoay quanh type và field, bạn quyết định hình dạng response ngay trong query. Query đầu tiên nên nhỏ (tên field dưới đây là giả định, hãy lấy tên thật trong schema):

query {
  order(id: "A-1024") {
    id
    status
  }
}

Lợi thế lớn khi khám phá schema của khách là kiểm tra trước khi chạy. Hệ thống type cho phép công cụ báo query sai cú pháp trước khi request chạm vào server. Bạn học schema bằng cách để công cụ chỉ ra chỗ sai, nhanh hơn nhiều so với đọc từ đầu đến cuối.

Kiểm tra: response có đúng hai field bạn hỏi, không thừa không thiếu. Sau đó thêm dần từng field theo nhu cầu của use case.

Bước 5: bọc lại, có timeout, rồi mới gọi là xong

Một lời gọi chạy được trên laptop chưa phải là tích hợp. Service của khách có thể phản hồi chậm hoặc treo, và code của bạn không nên chờ mãi. gRPC cho phép client đặt deadline, tức thời gian tối đa sẵn sàng chờ một RPC hoàn tất. Với SOAP và GraphQL, hãy đặt timeout tương đương ở HTTP client bạn dùng.

Viết một hàm kiểu get_order(order_id) che giấu giao thức bên dưới: nhận tham số đơn giản, trả về object của bạn, ném ra một loại lỗi thống nhất dù gốc là Fault của SOAP hay lỗi mà gRPC client trả về.

Đoạn dưới là khung minh họa giản lược bằng Python; hàm _goi_he_thong_khach là chỗ bạn đặt lời gọi SOAP, gRPC hoặc GraphQL thật từ bước 2, 3 hoặc 4, còn 5 giây chỉ là giá trị ví dụ:

# minh họa giản lược: thay _goi_he_thong_khach bằng lời gọi thật của bạn
class IntegrationError(Exception):
    pass

def get_order(order_id: str, timeout_s: float = 5.0) -> dict:
    try:
        raw = _goi_he_thong_khach(order_id, timeout=timeout_s)
    except Exception as e:  # Fault SOAP, lỗi gRPC, lỗi HTTP, hết thời gian chờ...
        raise IntegrationError(f"get_order({order_id}) thất bại: {e}") from e
    return {"id": raw["id"], "status": raw["status"]}

Kiểm tra: gọi get_order với một mã đúng và một mã sai. Lần đầu phải trả về dict gọn hai field, lần sau phải ra IntegrationError kèm thông báo đọc được, không phải một stack trace XML dài cả trang. Đội của bạn không cần biết bên dưới là XML hay Protocol Buffers.

Ba lỗi khiến một ngày thành một tuần

Lỗi phổ biến nhất là bắt đầu từ thứ khó nhất. Khách nhắc đến “stream sự kiện realtime” và bạn lao vào bidirectional streaming, trong khi một unary RPC đã đủ để chứng minh kết nối và lấy dữ liệu cho demo.

Kế đến là bỏ qua lỗi. Nhiều người chỉ thử đường đi thành công, rồi đến ngày demo gặp một Fault SOAP lạ mà code không xử lý được. Gửi cố ý một request sai ngay trong ngày đầu tốn năm phút và có thể cứu cả một buổi demo.

Cuối cùng là gọi không có giới hạn thời gian. Không có deadline hay timeout, một service treo sẽ kéo cả pipeline treo theo, và bạn sẽ mất cả buổi chiều tìm lỗi ở sai chỗ.

Đưa kỹ năng này vào CV thế nào?

Khi JD FDE nhắc đến “tích hợp với hệ thống legacy” hay “API nội bộ của khách”, đừng chỉ đáp lại bằng dòng “SOAP, gRPC, GraphQL” ở mục kỹ năng.

Hãy viết một dòng kết quả, ví dụ “tích hợp service SOAP qua WSDL, bọc thành client có timeout và xử lý Fault”, hoặc dẫn link một repo nhỏ có client cho cả ba giao thức gọi vào server bạn tự dựng.

Ở khách, người được tin tưởng không phải là người thuộc lòng đặc tả SOAP 1.2. Đó là người trước bữa trưa ngày đầu đã gửi lên kênh chung một dòng: “Đã gọi được GetOrder, đây là dữ liệu mẫu.”

6 nguồn
Đọc tiếp trên lộ trình · Chặng 2: Kỹ thuật rộngKafka và Flink cho FDE: ghép dòng dữ liệu của khách vào model chấm điểm thời gian thựcModel chạy tốt trên notebook là chuyện dễ. Khách sẽ hỏi bạn những câu khó hơn: có mất message không, có chấm trùng không, model chậm thì pipeline sẽ ra sao.