Thực hành tốt nhất về thiết kế API trong Laravel

Bị đánh cắp từ đây.

Bài đăng này có phiên bản âm thanh nhờ ứng dụng Blogcast của Miguel Piedrafita.

Tôi không chỉ là một Kỹ sư DevOps, mà tôi cũng đã bắt đầu từ con số 0 với PHP từ khi còn nhỏ, trở lại những ngày tôi học lớp 5. Kể từ đó, tôi đã liên tục cải thiện mã của mình và tôi phát hiện ra rằng mọi người đã áp dụng một số loại tiêu chuẩn cho mã sạch hơn, trực quan hóa tốt hơn và vì chúng là tiêu chuẩn, mọi người có thể hiểu rõ hơn mọi nhà phát triển khác đã viết trong cùng một cơ sở mã.

Tôi luôn thích viết mã nhiều hơn trong phần phụ trợ hơn là ở phần đầu. Tôi đã cố gắng trở thành một Full Stack, nhưng nó không phù hợp với tôi. Vì vậy, tôi đã quay trở lại để viết phụ trợ, đặc biệt là các API. Lần này, tôi đã nói về các tiêu chuẩn mã hóa nói chung, nhưng tôi sẽ nói về những API thực sự hoạt động và làm thế nào để phát triển chúng dễ dàng hơn, từ bảo mật đến các mẹo về cách làm điều đó tốt hơn.

Về cơ bản, API là một giao diện trả về dữ liệu ở định dạng đặc biệt mà bất kỳ loại ứng dụng nào, dù là ứng dụng Android hay ứng dụng web đều có thể hiểu được.

JSON được sử dụng rộng rãi, vì nó gần như ở khắp mọi nơi. Tùy chọn khác là sử dụng XML, nhưng tôi gặp rắc rối với một số API của bên thứ ba (đặc biệt là các nhà cung cấp dịch vụ thanh toán ở nước tôi) đã sử dụng XML qua JSON và sự phát triển là hoàn toàn tào lao. Tôi luôn khuyên bạn nên phát triển API JSON, trừ khi có ai đó yêu cầu API XML.

Khi phát triển API, bạn cần cân nhắc một số điều, theo thứ tự cụ thể này:

  • bảo mật - bảo mật nó bằng OAuth, khóa API hoặc CORS là bắt buộc. Tùy chọn, bạn nên sử dụng một bộ điều tiết để giới hạn các yêu cầu cho ứng dụng của bạn.
  • tiêu đề - đảm bảo rằng ứng dụng của bạn gửi đúng loại nội dung. Tiêu đề loại nội dung là một chút thông tin cho khách hàng nhận dữ liệu: Đây là thứ tôi gửi cho bạn là JSON JSON hoặc ở đây là XML. phân tích nó đúng cách, vì vậy trình duyệt hoặc máy khách của bạn biết cách giải mã chính xác.
  • tiêu chuẩn mã hóa và đặt tên - đây hoàn toàn là phụ trợ. Hãy chắc chắn rằng bạn phù hợp với câu trả lời của bạn. Chỉ dính vào một loại đặt tên và định dạng thích hợp.

Tôi thích mã hóa API trong Laravel vì bạn muốn mở rộng hơn nữa với Phát sóng sự kiện hoặc các tính năng Lumen bị thiếu khác làm cho nó nhanh chóng, bạn có thể làm điều đó mà không cần viết lại toàn bộ dự án từ đầu. Trong trường hợp bạn sẽ ở mức tối thiểu, hãy sử dụng Lumen.

Bảo vệ

Vấn đề lớn nhất bạn nên quan tâm là bảo mật. Nó dễ dàng bảo mật nó, nhưng nếu không thực hiện đúng cách, bạn có thể có quyền truy cập không mong muốn. Trong Laravel, bạn có thể muốn sử dụng Hộ chiếu Laravel - nó thuộc hệ sinh thái Laravel, hỗ trợ xác thực thông qua ID ứng dụng đó - App Secret để lấy mã thông báo truy cập, để mạo danh ai đó hoặc máy chủ, hoặc là phụ trợ hoặc phụ trợ. Về cơ bản, bạn sẽ đưa ra yêu cầu với ID ứng dụng và Bí mật ứng dụng của mình đến điểm cuối OAuth để nhận mã thông báo, có thể được tạo bởi máy chủ (nghĩa là truy cập API từ lệnh chạy trong cronjob mỗi ngày) hoặc bởi người dùng đã đăng nhập vào ứng dụng của bạn.

Ngoài ra, bạn có thể muốn sử dụng xác thực Mã thông báo JWT, chạy gần như giống nhau, nhưng có lẽ nó dễ hiểu hơn. Chọn lựa chọn của bạn và xem cái nào phù hợp hơn với bạn, cả trong việc thực hiện và nhu cầu của bạn.

Tiêu đề

Yêu cầu web chỉ là các cuộc hội thoại bình thường giữa máy khách và máy chủ hoặc giữa hai máy chủ. Họ dựa vào một yêu cầu và một phản hồi, trừ khi đó là một loại yêu cầu websocket, nhưng đó chỉ là một câu chuyện khác. Khi yêu cầu hoặc gửi lại mọi thứ, có một số thông tin được gọi là Tiêu đề cần được chăm sóc - một số trong số chúng cho máy chủ biết cách xử lý thông tin đã nhận hoặc cách khách hàng muốn nhận câu trả lời.

Nó giống như mẹ bạn nói với bạn: Hãy đi mua sữa từ cửa hàng nhưng chỉ mua từ sữa nhãn hiệu X. Bạn biết phải làm gì, nhưng bạn phải chọn nó chỉ một loại sữa. Nó cũng giống như các yêu cầu: Bạn tôi muốn có được danh sách người dùng, nhưng hãy đưa cho tôi trong JSON, hoặc tôi muốn nhận tất cả người dùng, nhưng hãy gửi cho tôi trong số 20 người (trong trường hợp bạn chỉ định tham số GET ). Đối với điều này, có một tiêu đề gọi là Chấp nhận, có thể là ứng dụng / json trong trường hợp bạn muốn phản hồi dưới dạng JSON. Nó không phải là một điều bắt buộc, nhưng đối với một số ứng dụng như AJAX, nếu phát hiện ra tiêu đề đó, nó sẽ tự động giải mã phản hồi cho khách hàng mà không phải thực hiện điều gì đó như sau:

dữ liệu var = JSON.parse (respons.data);

Một tiêu đề khác bạn phải biết là Loại nội dung, hơi khó hiểu, nhưng nó ngược lại với Chấp nhận: nó cho máy chủ biết cách xử lý nội dung anh ta nhận được. Ví dụ: nếu bạn muốn gửi dữ liệu RAW, như chuỗi JSON, bạn có thể đặt Kiểu nội dung thành application / json, nhưng nếu bạn muốn nhận nội dung thông qua biến $ _POST, bạn nên đặt nó thành x-www -form-urlencoding. Điều này sẽ giúp bạn không chỉ phân tích nội dung trực tiếp thông qua $ _POST, mà nó còn được sử dụng trong các biểu mẫu HTML vì nó có thể truy cập dễ dàng. Ví dụ, nếu bạn gửi dữ liệu như nhị phân, thông qua đầu vào tệp, hãy đảm bảo bạn đã gửi dữ liệu đa dữ liệu / biểu mẫu.

Trong Laravel, won won này là một vấn đề vì bạn có thể truy cập dữ liệu trực tiếp.

Đối với ứng dụng / json:

chỉ số chức năng (Yêu cầu $ request)
{
   $ var = $ request-> biến;
}

Tuy nhiên, trong application / json bạn không thể thấy bằng cách sử dụng phương thức -> all () nội dung JSON:

chỉ số chức năng (Yêu cầu $ request)
{
   $ data = $ request-> all (); // đây là mảng trống, thậm chí chúng ta có dữ liệu.
}

Nếu được đặt thành x-www-form-urlencoding hoặc multiart / form-data, bạn có thể thấy tất cả các biến bằng cách sử dụng -> all ().

Khi trả lời lại, trong Laravel, bạn có thể sử dụng phản hồi JSON tích hợp HOẶC bạn có thể giải quyết vấn đề tốt hơn và sử dụng một gói như Laravel Fractal hoặc Laravel responder. Từ kinh nghiệm của riêng tôi, Phản hồi của Laravel đã thực hiện công việc tốt hơn, theo một cách thức ngữ nghĩa hơn. Tôi se cho bạn xem:

Hàm getUsers (Yêu cầu $ request)
{
   trả lời trả lời () -> thành công (Người dùng :: all ()) -> reply ();
}

Điều này sẽ trả về tất cả người dùng có trạng thái OK 200 và được định dạng dưới dạng JSON. Thật tuyệt phải không? Đối với các lỗi, bạn phải làm một cái gì đó như thế, cho phép bạn gửi mã và tin nhắn:

Hàm getUsers (Yêu cầu $ request)
{
   $ users = Người dùng :: all ();

   if ($ users-> Count () === 0) {
      trả lời trả lời () -> lỗi ('no_users', 'Không có người dùng.') -> reply ();
   }
   trả lời trả lời () -> thành công ($ users) -> reply ();
}

Gói này hỗ trợ nhiều hơn, vì vậy hãy tìm đến các tài liệu vì nó có thể dễ dàng tích hợp với các máy biến áp và dữ liệu tùy chỉnh được gửi.

Tiêu chuẩn mã hóa

Những gì tôi thích nhìn thấy là mọi người gắn bó với một số tiêu chuẩn phù hợp với họ, hoặc là sạch sẽ. Dưới đây là một số mẹo có thể giúp bạn xây dựng mã sạch hơn và cấu trúc các tuyến API của bạn tốt hơn.

Sử dụng tệp tuyến / api.php cho các tuyến API

Laravel đi kèm với một tuyến / api.phpfile riêng biệt làm chậm lại tệp tuyến / web.php thông thường được sử dụng để định tuyến web. Tệp api.php được tạo để lưu trữ các tuyến API của bạn. Nó có một phần mềm trung gian được áp dụng trên tàu (có thể thấy trong app / Http / Kernel.php, trong biến $ middlewaregroup, dưới api) và tiền tố của / api, vì vậy tất cả các tuyến được xác định đã có sẵn cho / api

Sử dụng tên tuyến

Những gì tôi muốn làm là đặt cài đặt thành toàn bộ API, vì vậy tôi có thể truy cập các tuyến theo tên của chúng, với api. tiếp đầu ngữ.

Tuyến đường :: get ('/ users', 'API \ UserControll @ getUsers') -> name ('get.users');

Tuyến đường này URL có thể được sử dụng tuyến đường ('get.users'), nhưng nó có thể xung đột với web.php.

Tuyến :: nhóm (['as' => 'api.'], Hàm () {
   Tuyến đường :: get ('/ users', 'API \ UserControll @ getUsers') -> name ('get.users');
});

Bằng cách này, bạn sẽ có nó trên tuyến đường ('api.get.users').

Nếu bạn sử dụng cách đặt tên tuyến đường, nếu bài kiểm tra viết của bạn, bạn đã thắng Thay cần URL ở mọi nơi nếu bạn định thay đổi vị trí URL và giữ tên tuyến.

Các tuyến đường mô tả nhưng đơn giản

Một thực hành tốt là nhóm các tuyến thành các phần, như người dùng, bài đăng, v.v. và sử dụng những điều đơn giản nhất bạn có thể nghĩ đến:

Tuyến :: nhóm (['as' => 'api.'], Hàm () {
   Tuyến đường :: nhóm (['dưới dạng' => 'tài khoản.', 'Tiền tố' => '/ tài khoản'], hàm () {
         Tuyến đường :: get ('/ users', 'API \ UserControll @ getUsers') -> name ('get.users');
         Tuyến đường :: get ('/ user / {id}', 'API \ UserControll @ getUser') -> name ('get.user');
         Route :: post ('/ user', 'API \ UserControll @ createUser') -> name ('create.user');
         // Vân vân.
   });
});

Sử dụng :: get () để nhận dữ liệu, :: post () để tạo, :: patch () hoặc :: put () để chỉnh sửa và :: xóa () để xóa dữ liệu. Như thế này, cuối cùng bạn sử dụng cùng một điểm cuối, nhưng với các loại yêu cầu khác nhau, bạn sẽ có thể kích hoạt các hành động khác.

Trong bộ điều khiển của bạn, bạn nên sử dụng mã hóa đơn giản và sử dụng các lớp Yêu cầu, như tôi đã giải thích trong Đẩy thêm Laravel - mẹo hay nhất và cách thực hành tốt cho Laravel 5.7

Hàm getUsers (Yêu cầu $ request)
{
   $ users = Người dùng :: all ();
   trả lời trả lời () -> thành công ($ users) -> reply ();
}
Hàm getUser ($ id, Request $ request)
{
   $ user = Người dùng :: findOrFail ($ id);
   trả lời trả lời () -> thành công ($ user) -> reply ();
}
function createdUser (CreatUserRequest $ request)
{
    $ user = Người dùng :: tạo ($ request-> all ());
    trả lời trả lời () -> thành công ($ user) -> reply ();
}
// Vân vân.

Ngoài ra, hãy đảm bảo bạn tuân theo cùng một cách đặt tên cho tất cả các hành động, vì vậy bạn sẽ tìm thấy chúng nhanh hơn và bất kỳ ai cũng có thể truy cập vào cơ sở mã và giúp dễ dàng duy trì hoặc tạo nội dung. Don Patrick cam kết các khóa API hoặc dữ liệu nhạy cảm cho repo, viết mã sạch và háo hức học hỏi từ những người khác.

Quá khó hiểu? Tiếp cận với tôi!

Nếu bạn có thêm câu hỏi về Laravel, nếu bạn cần trợ giúp với bất kỳ thông tin nào liên quan đến DevOps hoặc chỉ muốn nói một lời cảm ơn!, Bạn có thể tìm thấy tôi trên Twitter @rennokki!

Tham gia cộng đồng Slack của chúng tôi và đọc các chủ đề Faun hàng tuần của chúng tôi

Nếu bài đăng này hữu ích, vui lòng nhấp vào nút vỗ tay bên dưới một vài lần để thể hiện sự hỗ trợ của bạn cho tác giả! ⬇