Top 4 # Xem Nhiều Nhất Cách Viết 1 Api Mới Nhất 3/2023 # Top Like | Hanoisoundstuff.com

Bài 1: Cách Tạo Ứng Dụng Web Api

Trước khi tạo ứng dụng chúng tôi Web API, chúng ta sẽ tìm hiểu API là gì ?

API là viết tắt của Application Programming Interface, hiểu nôm na là giao tiếp lập trình ứng dụng.

Theo Wikipedia: “Trong lập trình máy tính, một API là một tập các chương trình con, các giao thức, các công cụ để xây dựng ứng dụng và phần mềm.”

Hiểu một cách đơn giản, API là cổng giao tiếp gồm các chương trình con, hàm được xây dựng sẵn, cho phép các lập trình viên truy cập và sử dụng các chức năng hoặc dữ liệu của ứng dụng, hệ điều hành hoặc các dịch vụ.

ASP.NET Web API là một framework cho phép xây dựng các dịch vụ dựa trên HTTP mà có thể được truy xuất từ nhiều ứng dụng trên các nền tảng khác nhau như windows, web hay mobile, v.v…

Cách tạo ứng dụng chúng tôi Web Api sử dụng Visual Studio 2017

Bên trái, các bạn chọn loại ứng dụng Web

Chọn .Net Framework 4.6.1, và chúng tôi Web Application

Trong mục Name, các bạn nhập tên của dự án, ở đây tôi nhập vào HienMinhWebAPI

Nhấn OK để sang bước tiếp theo

Bước 2: Trong cửa sổ New chúng tôi Web Application, các bạn chọn Empty, sau đó nhấn OK

Bước 4: Trong cửa sổ Nuget, các bạn thực hiện lần lượt theo thứ tự như trong hình. Nhấn Install để cài đặt.

Bước 5: Trong cửa sổ Preview Changes, các bạn nhấn OK để xác nhận cài đặt các thư viện phụ thuộc.

Bước 6: Trong project HienMinhWebAPI các bạn tạo 2 thư mục Configuration và Controllers như hình

Bước 7: Trong thư mục Configuration, các bạn tạo file chúng tôi rồi viết đoạn mã sau:

Bước 9: File chúng tôi được thêm vào ứng dụng. Các bạn cần định tuyến Web API khi ứng dụng được khởi chạy bằng cách viết đoạn mã sau trong Application_Start

Bước 10: Tạo một Controller trong thư mục Controllers như sau:

Bước 11: Trong cửa sổ, Add Scaffold, các bạn chọn Web API 2 Controoler – Empty. Tại cửa sổ Add Controller, các bạn nhập DemoController tại ô Controller Name. Sau đó, nhấn Add để tạo controller.

Bước 12: Trong file DemoController. Các bạn viết đoạn mã sau

Bước 13: Nhấn F5 để chạy, các bạn truy cập theo đường dẫn sau để xem kết quả: http://localhost:xxxx/api/Demo

Trong đó: xxxx là số cổng mặc định của IIS trên máy các bạn

Trên máy của tôi, địa chỉ sẽ như sau: http://localhost:50468/api/Demo

Restful Api Là Gì? Cách Thiết Kế Restful Api

Có thể nói nguyên lí và cấu trúc dữ liệu RESTful được biết đến rộng rãi trong giới lập trình web nói chung và lập trình ứng dụng nói riêng.

Có thể nói bản thân REST không phải là một loại công nghệ. Nó là phương thức tạo API với nguyên lý tổ chức nhất định. Những nguyên lý này nhằm hướng dẫn lập trình viên tạo môi trường xử lý API request được toàn diện.

Để hiểu rõ hơn về RESTful API ta sẽ đi lần lượt giải thích các khái niệm API, REST hay RESTful.

RESTful API là một tiêu chuẩn dùng trong việc thiết kế API cho các ứng dụng web (thiết kế Web services) để tiện cho việc quản lý các resource. Nó chú trọng vào tài nguyên hệ thống (tệp văn bản, ảnh, âm thanh, video, hoặc dữ liệu động…), bao gồm các trạng thái tài nguyên được định dạng và được truyền tải qua HTTP.

API ( Application Programming Interface) là một tập các quy tắc và cơ chế mà theo đó, một ứng dụng hay một thành phần sẽ tương tác với một ứng dụng hay thành phần khác. API có thể trả về dữ liệu mà bạn cần cho ứng dụng của mình ở những kiểu dữ liệu phổ biến như JSON hay XML.

REST ( REpresentational State T ransfer) là một dạng chuyển đổi cấu trúc dữ liệu, một kiểu kiến trúc để viết API. Nó sử dụng phương thức HTTP đơn giản để tạo cho giao tiếp giữa các máy. Vì vậy, thay vì sử dụng một URL cho việc xử lý một số thông tin người dùng, REST gửi một yêu cầu HTTP như GET, POST, DELETE, vv đến một URL để xử lý dữ liệu.

RESTful API là một tiêu chuẩn dùng trong việc thiết kế các API cho các ứng dụng web để quản lý các resource. RESTful là một trong những kiểu thiết kế API được sử dụng phổ biến ngày nay để cho các ứng dụng (web, mobile…) khác nhau giao tiếp với nhau.

Chức năng quan trọng nhất của REST là quy định cách sử dụng các HTTP method (như GET, POST, PUT, DELETE…) và cách định dạng các URL cho ứng dụng web để quản các resource. RESTful không quy định logic code ứng dụng và không giới hạn bởi ngôn ngữ lập trình ứng dụng, bất kỳ ngôn ngữ hoặc framework nào cũng có thể sử dụng để thiết kế một RESTful API.

RESTful hoạt động như thế nào?

GET (SELECT): Trả về một Resource hoặc một danh sách Resource.

POST (CREATE): Tạo mới một Resource.

PUT (UPDATE): Cập nhật thông tin cho Resource.

DELETE (DELETE): Xoá một Resource.

Những phương thức hay hoạt động này thường được gọi là CRUD tương ứng với Create, Read, Update, Delete – Tạo, Đọc, Sửa, Xóa.

Hiện tại đa số lập trình viên viết RESTful API giờ đây đều chọn JSON là format chính thức nhưng cũng có nhiều người chọn XML làm format, nói chung dùng thế nào cũng được miễn tiện và nhanh.

Authentication và dữ liệu trả về

RESTful API không sử dụng session và cookie, nó sử dụng một access_token với mỗi request. Dữ liệu trả về thường có cấu trúc như sau:

{ "data" : { "id": "1", "name": "TopDev" } }

Status code

Khi chúng ta request một API nào đó thường thì sẽ có vài status code để nhận biết sau:

200 OK – Trả về thành công cho những phương thức GET, PUT, PATCH hoặc DELETE.

201 Created – Trả về khi một Resouce vừa được tạo thành công.

204 No Content – Trả về khi Resource xoá thành công.

304 Not Modified – Client có thể sử dụng dữ liệu cache.

400 Bad Request – Request không hợp lệ

401 Unauthorized – Request cần có auth.

403 Forbidden – bị từ chối không cho phép.

404 Not Found – Không tìm thấy resource từ URI

405 Method Not Allowed – Phương thức không cho phép với user hiện tại.

410 Gone – Resource không còn tồn tại, Version cũ đã không còn hỗ trợ.

415 Unsupported Media Type – Không hỗ trợ kiểu Resource này.

422 Unprocessable Entity – Dữ liệu không được xác thực

429 Too Many Requests – Request bị từ chối do bị giới hạn

Nên sử dụng Version

Luôn sử dụng version để khi bạn cần nâng cấp API mà vẫn hỗ trợ các API cũ.

Xây dựng API với Laravel

Lấy việc xây dựng api trên Laravel để làm ví dụ, trước khi đi vào ta tổng quan về Http Request.

HTTP Request

HTTP request có tất cả 9 loại method , 2 loại được sử dụng phổ biến nhất là GET và POST

GET: được sử dụng để lấy thông tin từ server theo URI đã cung cấp.

HEAD: giống với GET nhưng response trả về không có body, chỉ có header.

POST: gửi thông tin tới sever thông qua các biểu mẫu http.

PUT: ghi đè tất cả thông tin của đối tượng với những gì được gửi lên.

PATCH: ghi đè các thông tin được thay đổi của đối tượng.

DELETE: xóa tài nguyên trên server.

CONNECT: thiết lập một kết nối tới server theo URI.

OPTIONS: mô tả các tùy chọn giao tiếp cho resource.

TRACE: thực hiện một bài test loop – back theo đường dẫn đến resource.

RESTful Route

Viết Api thì sẽ khai báo router vào file routes/api.php thay vì sử dụng file routes/web.php. Các setting mặc cho file api.php trong laravel:

Url: những route được khai báo trong file này mặc định có prefix url là api (ví dụ: topdev.vn/api/products)

Middleware: mặc định sẽ được gán Middleware Group là api, trong file app/Http/Kernel sẽ thấy 2 middleware thuộc Middleware Group: api là throttle (giới hạn request / time) và bindings (model binding).

Có thể tùy chỉnh giá trị mặc định này trong method mapApiRoutes trong file app/Providers/RouteServiceProvider.php

Tạo các route để thực hiện các thao tác như CRUD (Create, Read, Update, Delete):

# Sử dụng put nếu update toàn bộ các field # Sử dụng patch nếu update 1 vài field

Mặc định route đã được gán middleware bindings, nếu muốn sử dụng model binding trong controller thì chúng ta sửa lại tham số trong route như sau:

Ngoài ra trong laravel cũng hỗ trợ chúng ta 1 cách khai báo ngắn gọn hơn:

Resource Controllers

Tương ứng với các Route RESTful đã khai báo ở trên, đặc biệt nếu dùng method apiResource thì laravel cũng hỗ trợ các method xử lí tương ứng trong controller.

Để tạo ra Resource Controllers chúng ta chạy lệnh sau

php artisan make:controller Api/ProductController -api File ProductController tạo ra sẽ như sau<?php namespace AppHttpControllersApi; use IlluminateHttpRequest; use AppHttpControllersController; class ProductController extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index() { } /** * Store a newly created resource in storage. * * @param IlluminateHttpRequest $request * @return IlluminateHttpResponse */ public function store(Request $request) { } /** * Display the specified resource. * * @param int $id * @return IlluminateHttpResponse */ public function show($id) { } /** * Update the specified resource in storage. * * @param IlluminateHttpRequest $request * @param int $id * @return IlluminateHttpResponse */ public function update(Request $request, $id) { } /** * Remove the specified resource from storage. * * @param int $id * @return IlluminateHttpResponse */ public function destroy($id) { } }

Ngoài ra nếu muốn sử dụng model binding khi tạo Resource Controllers thì dùng lệnh bên dưới

php artisan make:controller Api/ProductController --api --model=Models/Product

File ProductController tạo ra sẽ như sau, chúng ta để ý tham số của các method show, update, destroy sẽ thay đổi 1 chút.

<?php namespace AppHttpControllersApi; use AppModelsProduct; use IlluminateHttpRequest; use AppHttpControllersController; class ProductController extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index() { } /** * Store a newly created resource in storage. * * @param IlluminateHttpRequest $request * @return IlluminateHttpResponse */ public function store(Request $request) { } /** * Display the specified resource. * * @param AppModelsProduct $product * @return IlluminateHttpResponse */ public function show(Product $product) { } /** * Update the specified resource in storage. * * @param IlluminateHttpRequest $request * @param AppModelsProduct $product * @return IlluminateHttpResponse */ public function update(Request $request, Product $product) { } /** * Remove the specified resource from storage. * * @param AppModelsProduct $product * @return IlluminateHttpResponse */ public function destroy(Product $product) { } }

Demo 1 đoạn code đơn giản trong controller kết hợp với model binding và route apiResource khi xây dựng API:

<?php namespace AppHttpControllersApi; use AppHttpControllersController; use AppModelsProduct; use IlluminateHttpRequest; class ProductController extends Controller { /** * Display a listing of the resource. * */ public function index() { return Product::all(); } /** * Store a newly created resource in storage. * * @param Request $request */ public function store(Request $request) { } /** * Display the specified resource. * * @param Product $product * @return Product */ public function show(Product $product) { return $product; } /** * Update the specified resource in storage. * * @param Request $request * @param Product $product * @return bool */ public function update(Request $request, Product $product) { } /** * Remove the specified resource from storage. * * @param Product $product * @throws Exception */ public function destroy(Product $product) { } }

Mặc định khi sử dụng route apiResource thì dữ liệu trả về sẽ tự động được chuyển sang kiểu JSON và sẽ có status tương ứng nên chỉ cần return dữ liệu ra là được.

Còn nếu muốn tùy biến status trả về thì có thể tham khảo cách phía dưới có sử dụng class IlluminateHttpResponse để lấy status thay vì fix giá trị vào ví dụ như HTTP_OK tương ứng sẽ là 200

<?php namespace AppHttpControllers; use AppModelsProduct; use IlluminateHttpRequest; use IlluminateHttpResponse; class ProductController extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpJsonResponse */ public function index() { $products = Product::all(); } } Eloquent Resources

Khi xây dựng API, bạn có thể cần transform dữ liệu từ controller trước khi trả về cho người dùng ứng dụng của bạn, laravel cũng đã hỗ trợ điều này với Eloquent Resources

Để tạo ra 1 class chuyển đổi chúng ta chạy lệnh sau

php artisan make:resource Product

File app/Http/Resources/Product.php sẽ có nội dung như sau

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonJsonResource; class Product extends JsonResource { /** * Transform the resource into an array. * * @param IlluminateHttpRequest $request * @return array */ public function toArray($request) { return parent::toArray($request); } }

Mình sẽ tùy chỉnh dữ liệu trả về là chỉ có title và price

<?php namespace AppHttpResources; use IlluminateHttpResourcesJsonJsonResource; class Product extends JsonResource{ /** * Transform the resource into an array. * * @param IlluminateHttpRequest $request * @return array */ public function toArray($request){ return [ ]; } }

Ở controller thì mình sẽ sửa lại như sau

<?php namespace AppHttpControllersApi; use AppHttpControllersController; use AppModelsProduct; use IlluminateHttpRequest; use AppHttpResourcesProduct as ProductResource; class ProductController extends Controller{ /** * Display a listing of the resource. * */ public function index(){ $products = Product::all(); return ProductResource::collection($products); } /** * Store a newly created resource in storage. * * @param Request $request */ public function store(Request $request){ return new ProductResource($product); } /** * Display the specified resource. * * @param Product $product * @return Product */ public function show(Product $product){ return new ProductResource($product); } /** * Update the specified resource in storage. * * @param Request $request * @param Product $product * @return bool */ public function update(Request $request, Product $product){ } /** * Remove the specified resource from storage. * * @param Product $product * @throws Exception */ public function destroy(Product $product){ } }

Authorization

Hiện tại có 3 cơ chế Authorize chính:

Tùy thuộc vào service của bạn, mà hãy chọn loại Authorize có mức độ phù hợp, cố gắng giữ nó càng đơn giản càng tốt.

CORS Policy

Viết API thì cũng cần chú ý về CORS là gì?

API Document

API document là một phần tương tự như Unit Test vậy - lấy ngắn để nuôi dài.

Mô tả đầy đủ về params request: gồm những params nào, datatype, require hay optional.

Nên đưa ra các ví dụ về HTTP requests và responses với data chuẩn.

Cập nhật Docs thường xuyên, để sát nhất với API có bất cứ thay đổi gì.

Format, cú pháp cần phải nhất quán, mô tả rõ ràng, chính xác.

Cách Test Api Như Thế Nào?

Sau khi đọc xong series “test API với Postman” của mình, các bạn có thể nắm được cái kiến thức cơ bản của API và các chức năng của Postman đem lại. Nhưng cách sắp xếp test và viết Testcase cho API như thế nào thì vẫn có vẻ chưa thông lắm, nên hôm nay mình sẽ viết 1 bài về cách test API như thế nào cho hợp lý.

Ví dụ: Tôi muốn check API update_profile gồm 2 trường Name và Birthday. Trong đó trường Name là bắt buộc và phải lớn hơn 4 ký tự. Trường Birthday thì không bắt buộc nhập.

Cách xử lý của Server và Client (có thể không giống với cty bạn):

User vào màn hình Profile, sửa lại 2 trường Name và Birthday.

User ấn vào nút Update Profile (Code ở client sẽ check điều kiện của trường Name, nếu đúng thì submit gửi API, gọi là request, nếu sai sẽ hiện thông báo tương ứng).

Thông tin mới gồm Name và Birthday theo phong bì thư của API cập bến Server.

Server đọc thư và check điều kiện lại 1 lần nữa.

Nếu các thông tin Name và Birthday đều Valid thì 2 thông tin đó được cập nhật vào Database.

Server trả lại thông tin, gọi là response, về lại cho client thông báo rằng nó đã cập nhật thành công.

User nhìn thấy Name và Birthday của mình đã được thay đổi ở màn hình Profile.

Khi thực hiện test API, chính là việc chúng ta test các bước 4, 5 và 6. Dó đó, với 1 API đơn lẻ, chúng ta sẽ check 2 phần chính: – tạm gọi là Syntax Testing (Validate dữ liệu – bước 4 + bước 6) – và Funtional Testing (Test business logic – bước 5 và 6).

Syntax Testing

Loại này sẽ tập trung vào cái Method check điều kiện: Accept với data đúng và Reject với data sai hay không. Một vài ví dụ:

Bỏ trống trường bắt buộc → Trong Response sẽ phải có thông báo lỗi, các thông tin khác không được cập nhật. Server không thực hiện 1 business logic nào cả.

Bỏ trống trường không bắt buộc → Không có lỗi gì cả, Server vẫn thực hiện business logic.

Điền các thông tin sai kiểu định dạng, ví dụ trường thời gian lại điền chữ → Trong Response sẽ phải có thông báo lỗi…

Chốt lại: Cái này giống hệt như những trường hợp Validate dữ liệu, chúng ta vẫn hay làm hàng ngày.

Functional Testing

Loại này check các Method xử lý dữ liệu và thực hiện 1 chức năng có đúng hay không. Ví dụ:

Giá là X và số phần trăm discount là Y thì số tiền phải trả là X*(1-Y) hay không → Nó chính là việc test Method tính toán với các tham số X và Y mà thôi. Việc thực hiện business logic có thể không lưu kết quả vào DB.

Việc Update trường Name ở ví dụ ban đầu có được lưu vào DB hay không? → mở DB ra và check kết quả.

Yêu cầu trả về thông tin của những user có tên là “Nam” → Vào DB thực hiện câu Query và so sánh với Response xem 2 kết quả có khớp nhau hay ko…

Test scenarios

Cuối cùng là ta ghép các API lại với nhau sẽ nó có bị lỗi ở đâu không? Chỗ này chính là những cái Test Suite, gộp nhiều Test Case lại.

Ví dụ như hình:

Khi sử dụng Postman, hãy để mỗi trường hợp là 1 API riêng biệt, không test đè lên nhau, sau khó kiểm soát và không tạo được test case cho automation.

Để không phải căng mắt check từng response của các trường hợp đơn lẻ, hãy đọc lại bài 9.

Bài viết dựa trên bài ” API testing best practices ” của Bas Dijkstra

API Testing với Postman (Phần 12) – Run Test Suites từ Runner

Laravel: Hướng Dẫn Laravel Api: Cách Xây Dựng Và Kiểm Tra Một Restful Api

Với sự phát triển của khung phát triển di động và JavaScript, sử dụng API RESTful là tùy chọn tốt nhất để xây dựng một giao diện duy nhất giữa dữ liệu của bạn và máy khách của bạn.

Trong hướng dẫn này, chúng ta sẽ khám phá những cách bạn có thể xây dựng và thử nghiệm API mạnh mẽ bằng cách sử dụng Laravel với xác thực. Chúng ta sẽ sử dụng Laravel 5.x.

API RESTful

Trước tiên, chúng ta cần hiểu chính xác những gì được coi là API RESTful. REST là viết tắt của REpresentational State Transfer và là một kiểu kiến ​​trúc để giao tiếp mạng giữa các ứng dụng, dựa trên giao thức không trạng thái (thường là HTTP) để tương tác.

Động từ HTTP đại diện cho hành động

Trong API RESTful, chúng ta sử dụng các động từ HTTP làm hành động và các điểm cuối là tài nguyên được tác động. Chúng ta sẽ sử dụng các động từ HTTP cho ý nghĩa ngữ nghĩa của chúng:

GET: lấy tài nguyên

POST: tạo tài nguyên

PUT: cập nhật tài nguyên

DELETE: xóa tài nguyên

Cập nhật hành động: PUT so với POST

API RESTful là một vấn đề của nhiều cuộc tranh luận và có rất nhiều ý kiến trên mạng về việc là tốt nhất để cập nhật với POST, PATCH hay PUT, hoặc nếu hành động tạo ra là tốt nhất còn lại để các PUT động từ. Trong bài viết này, chúng tôi sẽ sử dụng PUT cho hành động cập nhật, theo HTTP RFC, PUT có nghĩa là tạo/cập nhật tài nguyên tại một vị trí cụ thể. Một yêu cầu khác cho động từ PUT là idempotence, trong trường hợp này về cơ bản có nghĩa là bạn có thể gửi yêu cầu đó 1, 2 hoặc 1000 lần và kết quả sẽ giống nhau: một tài nguyên được cập nhật trong cơ sở dữ liệu.

Tài nguyên

Tài nguyên sẽ là mục tiêu của các hành động, trong trường hợp của chúng tôi là Bài viết và Người dùng và chúng có điểm cuối riêng:

Trong hướng dẫn api laravel này, các tài nguyên sẽ có tỷ lệ 1:1 trên các mô hình dữ liệu của chúng ta, nhưng đó không phải là một yêu cầu. Bạn có thể có các tài nguyên được thể hiện trong nhiều hơn một mô hình dữ liệu (hoặc hoàn toàn không được đại diện trong cơ sở dữ liệu) và các mô hình hoàn toàn vượt quá giới hạn cho người dùng. Cuối cùng, bạn có thể quyết định cách kiến ​​trúc sư tài nguyên và mô hình theo cách phù hợp với ứng dụng của bạn.

Lưu ý về tính nhất quán

Ưu điểm lớn nhất của việc sử dụng một tập hợp các quy ước như REST là API của bạn sẽ dễ dàng tiêu thụ và phát triển hơn nhiều. Một số điểm cuối khá đơn giản và do đó, API của bạn sẽ dễ sử dụng và bảo trì hơn nhiều so với việc có các điểm cuối như GET /get_article?id_article=12 và POST /delete_article?number=40. Tôi đã xây dựng các API khủng khiếp như thế trong quá khứ và tôi vẫn ghét bản thân mình vì nó.

Tuy nhiên, sẽ có những trường hợp khó có thể ánh xạ tới lược đồ Create/Retrieve/Update/Delete. Hãy nhớ rằng các URL không được chứa động từ và tài nguyên không nhất thiết phải là hàng trong một bảng. Một lưu ý khác là bạn không phải thực hiện mọi hành động cho mọi tài nguyên.

Thiết lập dự án web service của Laravel

Như với tất cả các framework PHP hiện đại, chúng tôi sẽ cần Composer để cài đặt và xử lý các phụ thuộc của chúng tôi. Sau khi bạn làm theo các hướng dẫn tải xuống (và thêm vào biến môi trường đường dẫn của bạn), hãy cài đặt Laravel bằng lệnh:

$ composer global require laravel/installer

Sau khi cài đặt kết thúc, bạn có thể tạo ra một ứng dụng mới như thế này:

Đối với lệnh trên, bạn cần phải có ~/composer/vendor/bin trong $PATH. Nếu bạn không muốn giải quyết vấn đề đó, bạn cũng có thể tạo một dự án mới bằng Composer:

$ composer create-project --prefer-dist laravel/laravel myapp

Với cài đặt Laravel, bạn sẽ có thể khởi động máy chủ và kiểm tra xem mọi thứ có hoạt động không:

Di chuyển và mô hình

Trước khi thực sự viết di chuyển đầu tiên của bạn, hãy đảm bảo bạn đã tạo cơ sở dữ liệu cho ứng dụng này và thêm thông tin đăng nhập vào .env tệp nằm trong thư mục gốc của dự án.

DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret

Bạn cũng có thể sử dụng Homestead, một hộp Vagrant được chế tạo đặc biệt cho Laravel, nhưng đó là một chút ngoài phạm vi của bài viết này.

Hãy bắt đầu với mô hình đầu tiên của chúng ta và di chuyển Điều khoản. Bài viết nên có một tiêu đề và một lĩnh vực cơ thể, cũng như một ngày sáng tạo. Laravel cung cấp một số lệnh thông qua công cụ dòng lệnh Artisan của Laravel giúp chúng ta bằng cách tạo các tệp và đặt chúng vào các thư mục chính xác. Để tạo mô hình Bài viết, chúng ta có thể chạy:

$ php artisan make:model Article -m

Tùy chọn -m là chữ viết tắt --migration và nó nói với Artisan để tạo ra một mô hình của chúng tôi. Đây là di chuyển được tạo:

Chúng ta hãy mổ xẻ điều này trong một giây:

Các phương thức up() và down() sẽ được chạy khi chúng ta di chuyển và khôi phục tương ứng;

Và cuối cùng, Schema::dropIfExists() tất nhiên, sẽ bỏ bảng nếu nó tồn tại.

Ngoài ra, hãy thêm hai dòng vào up() phương thức của chúng tôi :

Bạn cũng có thể sử dụng tùy chọn --step ở đây và nó sẽ tách từng di chuyển thành lô riêng để bạn có thể cuộn chúng lại nếu cần.

Bây giờ, hãy quay lại mô hình của chúng tôi và thêm các thuộc tính đó vào $fillable trường để chúng tôi có thể sử dụng chúng trong mô hình Article::create và Article::update mô hình của chúng tôi:

class Article extends Model { protected $fillable = ['title', 'body']; }

Các trường bên trong $fillable có thể được gán khối lượng bằng cách sử dụng các phương thức Eloquent create() và update(). Bạn cũng có thể sử dụng thuộc tính $guarded, để cho phép tất cả trừ một vài thuộc tính.

Cơ sở dữ liệu Seeding

Cơ sở dữ liệu seeding là quá trình điền vào cơ sở dữ liệu của chúng tôi với dữ liệu giả mà chúng ta có thể sử dụng để kiểm tra nó. Laravel đi kèm với Faker , một thư viện tuyệt vời để tạo ra định dạng chính xác của dữ liệu giả cho chúng tôi. Vì vậy, hãy tạo ra seeder đầu tiên của chúng tôi:

$ php artisan make:seeder ArticlesTableSeeder

Các seeder sẽ được đặt trong /database/seeds thư mục. Đây là giao diện sau khi chúng tôi thiết lập để tạo một vài bài viết:

Vì vậy, hãy chạy lệnh seed:

$ php artisan db:seed --class=ArticlesTableSeeder

Hãy lặp lại quy trình để tạo seeder cho người dùng:

Chúng ta có thể làm cho nó dễ dàng hơn bằng cách thêm các seeder của chúng ta vào DatabaseSeederlớp chính bên trong database/seeds thư mục:

Theo cách này, chúng ta có thể chạy đơn giản $ php artisan db:seedvà nó sẽ chạy tất cả các lớp được gọi trong run() phương thức.

Tuyến đường và bộ điều khiển

Hãy tạo các điểm cuối cơ bản cho ứng dụng của chúng tôi: tạo, truy xuất danh sách, truy xuất một điểm duy nhất, cập nhật và xóa. Trên routes/api.php tệp, chúng ta chỉ cần làm điều này:

Bây giờ hãy chuyển mã này sang Trình điều khiển riêng của nó:

$ php artisan make:controller ArticleController

ArticleControll.php:

Các routes/api.php tập tin:

Route::get('articles', '''''[email protected]'); Route::get('articles/{id}', 'articles',[email protected]'); Route::post('articles/{id}',[email protected]'); Route::put('articles/{id}',[email protected]'); Route::delete([email protected]');

Chúng tôi có thể cải thiện các điểm cuối bằng cách sử dụng ràng buộc mô hình tuyến đường ngầm. Bằng cách này, Laravel sẽ đưa Article cá thể vào các phương thức của chúng tôi và tự động trả về 404 nếu không tìm thấy. Chúng tôi sẽ phải thay đổi tệp tuyến đường và trên bộ điều khiển:

Route::get('articles', ''ArticleControl'''[email protected]'); Route::get('articles/{article}', 'articles',[email protected]'); Route::post('articles/{article}',[email protected]'); Route::put('articles/{article}',[email protected]'); Route::delete([email protected]');

Lưu ý về Mã trạng thái HTTP và Định dạng phản hồi

200: ĐƯỢC. Mã thành công tiêu chuẩn và tùy chọn mặc định.

201: Đối tượng được tạo. Hữu ích cho các storehành động.

204: Không có nội dung. Khi một hành động được thực hiện thành công, nhưng không có nội dung để trả về.

206: Nội dung một phần. Hữu ích khi bạn phải trả về một danh sách tài nguyên được phân trang.

400: Yêu cầu xấu. Tùy chọn tiêu chuẩn cho các yêu cầu không vượt qua xác nhận.

401: Không được phép. Người dùng cần được xác thực.

403: Cấm. Người dùng được xác thực, nhưng không có quyền để thực hiện một hành động.

404: Không tìm thấy. Điều này sẽ được trả lại tự động bởi Laravel khi không tìm thấy tài nguyên.

500: Lỗi máy chủ nội bộ. Lý tưởng nhất là bạn sẽ không trả lại một cách rõ ràng điều này, nhưng nếu có điều gì đó bất ngờ bị phá vỡ, đây là những gì người dùng của bạn sẽ nhận được.

503: Dịch vụ Không sẵn có. Khá tự giải thích, nhưng cũng có một mã khác sẽ không được trả lại rõ ràng bởi ứng dụng.

Gửi phản hồi 404 chính xác

Nếu bạn đã cố gắng tìm nạp tài nguyên không tồn tại, bạn sẽ bị ném ngoại lệ và bạn sẽ nhận được toàn bộ stacktrace, như thế này:

Chúng tôi có thể khắc phục điều đó bằng cách chỉnh sửa lớp trình xử lý ngoại lệ của chúng tôi, được đặt trong app/Exceptions/Handler.php, để trả về phản hồi JSON:

Đây là một ví dụ về sự trở lại:

{ data: "Resource not found" }

Nếu bạn đang sử dụng Laravel để phục vụ các trang khác, bạn phải chỉnh sửa mã để hoạt động với Accept tiêu đề, nếu không, lỗi 404 từ các yêu cầu thông thường cũng sẽ trả về JSON.

Trong trường hợp này, các yêu cầu API sẽ cần tiêu đề Accept: application/json.

Xác thực

Có nhiều cách để triển khai Xác thực API trong Laravel (một trong số đó là Hộ chiếu , một cách tuyệt vời để triển khai OAuth2), nhưng trong bài viết này, chúng tôi sẽ thực hiện một cách tiếp cận rất đơn giản.

Để bắt đầu, chúng ta cần thêm một api_tokentrường vào users bảng:

$ php artisan make:migration --table=users adds_api_token_to_users_table

Và sau đó thực hiện di chuyển:

Sau đó, chỉ cần chạy di chuyển bằng cách sử dụng:

$ php artisan migrate

Tạo điểm cuối đăng ký

Chúng tôi sẽ sử dụng RegisterController(trong Auth thư mục) để trả về phản hồi chính xác khi đăng ký. Laravel đi kèm với xác thực ngoài hộp, nhưng chúng ta vẫn cần phải điều chỉnh nó một chút để trả về phản hồi mà chúng ta muốn.

Bộ điều khiển sử dụng các đặc điểm RegistersUsers để thực hiện đăng ký. Đây là cách nó hoạt động:

Và chúng ta có thể liên kết nó trên tập tin tuyến đường:

Route::post(register, 'Auth[email protected]);

Trong phần trên, chúng tôi đã sử dụng một phương thức trên mô hình Người dùng để tạo mã thông báo. Điều này hữu ích để chúng tôi chỉ có một cách duy nhất để tạo mã thông báo. Thêm phương thức sau vào mô hình Người dùng của bạn:

Và đó là nó. Người dùng hiện đang đăng ký và nhờ xác nhận Laravel và ra khỏi xác thực hộp, name, email, password, và password_confirmationlĩnh vực được yêu cầu, và các thông tin phản hồi được xử lý tự động. Kiểm tra validator()phương thức bên trong RegisterController để xem các quy tắc được thực hiện như thế nào.

Đây là những gì chúng ta nhận được khi đạt điểm cuối đó:

$ curl -X POST http://localhost:8000/api/register -H "Accept: application/json" -H "Content-Type: application/json" -d '{"name": "John", "email": "[email protected]", "password": "toptal123", "password_confirmation": "toptal123"}' { "data": { "api_token":"0syHnl0Y9jOIfszq11EC2CBQwCfObmvscrZYo5o2ilZPnohvndH797nDNyAT", "created_at": "2017-06-20 21:17:15", "email": "[email protected]", "id": 51, "name": "John", "updated_at": "2017-06-20 21:17:15" } }​

Tạo một điểm cuối đăng nhập

Và chúng ta có thể liên kết nó trên tập tin tuyến đường:

Route::post('login', 'Auth[email protected]');

Bây giờ, giả sử các máy gieo hạt đã được chạy, đây là những gì chúng tôi nhận được khi gửi POST yêu cầu đến tuyến đường đó:

$ curl -X POST localhost:8000/api/login -H "Accept: application/json" -H "Content-type: application/json" -d "{"email": "[email protected]", "password": "toptal" }"

Để gửi mã thông báo trong yêu cầu, bạn có thể thực hiện bằng cách gửi một thuộc tính api_tokentrong tải trọng hoặc dưới dạng mã thông báo mang trong tiêu đề yêu cầu ở dạng Authorization: Bearer Jll7q0BSijLOrzaOSm5Dr5hW9cJRZAJKOzvDlxjKCXepwAeZ7JR6YP5zQqnw.

Đăng xuất

Với chiến lược hiện tại của chúng tôi, nếu mã thông báo bị sai hoặc bị thiếu, người dùng sẽ nhận được phản hồi không được xác thực (chúng tôi sẽ triển khai trong phần tiếp theo). Vì vậy, đối với điểm cuối đăng xuất đơn giản, chúng tôi sẽ gửi mã thông báo và nó sẽ bị xóa trên cơ sở dữ liệu.

routes/api.php:

Route::post('logout', 'Auth[email protected]');

AuthLoginController.php:

Sử dụng chiến lược này, bất kỳ mã thông báo nào mà người dùng có sẽ không hợp lệ và API sẽ từ chối quyền truy cập (sử dụng phần mềm trung gian, như được giải thích trong phần tiếp theo). Điều này cần được phối hợp với giao diện người dùng để tránh người dùng vẫn đăng nhập mà không có quyền truy cập vào bất kỳ nội dung nào.

Sử dụng Middleware để hạn chế quyền truy cập

Với phần api_token được tạo, chúng ta có thể chuyển đổi phần mềm trung gian xác thực trong tệp tuyến đường:

Và chúng tôi nhận được một kết quả như thế này:

Điều này là do chúng ta cần chỉnh sửa unauthenticatedphương thức hiện tại trên lớp Handler của chúng ta. Phiên bản hiện tại chỉ trả về JSON nếu yêu cầu có Accept: application/json tiêu đề, vì vậy hãy thay đổi nó:

Với bản sửa lỗi đó, chúng ta có thể quay lại các điểm cuối của bài viết để bọc chúng trong auth:api phần mềm trung gian. Chúng tôi có thể làm điều đó bằng cách sử dụng các nhóm tuyến đường:

Bằng cách này, chúng tôi không phải đặt phần mềm trung gian cho mỗi tuyến. Nó không tiết kiệm nhiều thời gian ngay bây giờ, nhưng khi dự án phát triển, nó giúp giữ các tuyến đường KHÔ.

Kiểm tra các điểm cuối của chúng tôi

Laravel bao gồm tích hợp với PHPUnit ngoài hộp với một phpunit.xml thiết lập đã được thiết lập. Khung này cũng cung cấp cho chúng tôi một số trợ giúp và các xác nhận bổ sung giúp cuộc sống của chúng tôi dễ dàng hơn nhiều, đặc biệt là để thử nghiệm API.

Có một số công cụ bên ngoài bạn có thể sử dụng để kiểm tra API của mình; tuy nhiên, kiểm tra bên trong Laravel là một giải pháp thay thế tốt hơn nhiều, chúng ta có thể có tất cả các lợi ích của việc kiểm tra cấu trúc và kết quả API trong khi vẫn giữ toàn quyền kiểm soát cơ sở dữ liệu. Ví dụ, đối với điểm cuối danh sách, chúng tôi có thể điều hành một vài nhà máy và khẳng định phản hồi có chứa các tài nguyên đó.

Để bắt đầu, chúng tôi cần điều chỉnh một vài cài đặt để sử dụng cơ sở dữ liệu SQLite trong bộ nhớ. Sử dụng điều đó sẽ làm cho các thử nghiệm của chúng tôi chạy nhanh như chớp, nhưng sự đánh đổi là một số lệnh di chuyển (chẳng hạn như các ràng buộc) sẽ không hoạt động đúng trong thiết lập cụ thể đó. Tôi khuyên bạn nên tránh xa SQLite khi kiểm tra khi bạn bắt đầu gặp lỗi di chuyển hoặc nếu bạn thích một bộ kiểm tra mạnh hơn thay vì chạy hiệu suất.

Chúng tôi cũng sẽ chạy di chuyển trước mỗi bài kiểm tra. Thiết lập này sẽ cho phép chúng tôi xây dựng cơ sở dữ liệu cho từng thử nghiệm và sau đó hủy nó, tránh mọi loại phụ thuộc giữa các thử nghiệm.

Sau đó kích hoạt SQLite phpunit.xmlbằng cách thêm biến môi trường DB_CONNECTION:

Một điều cuối cùng mà tôi muốn làm là thêm lệnh kiểm tra vào composer.json:

"scripts": { "test" : [ "vendor/bin/phpunit" ], ... },

Lệnh kiểm tra sẽ có sẵn như thế này:

$ composer test

Thiết lập các nhà máy cho các thử nghiệm của chúng tôi

Các nhà máy sẽ cho phép chúng tôi nhanh chóng tạo các đối tượng với dữ liệu phù hợp để thử nghiệm. Chúng nằm trong database/factoriesthư mục. Laravel ra khỏi hộp với một nhà máy cho Userlớp, vì vậy hãy thêm một cái cho Article lớp:

Các Faker thư viện đã được tiêm để giúp chúng tôi tạo ra định dạng đúng của dữ liệu ngẫu nhiên cho các mô hình của chúng tôi.

Thử nghiệm đầu tiên của chúng tôi

Chúng ta có thể sử dụng các phương thức khẳng định của Laravel để dễ dàng đạt điểm cuối và đánh giá phản ứng của nó. Hãy tạo thử nghiệm đầu tiên của chúng tôi, thử nghiệm đăng nhập, sử dụng lệnh sau:

$ php artisan make:test Feature/LoginTest

Và đây là bài kiểm tra của chúng tôi:

Những phương pháp này kiểm tra một vài trường hợp đơn giản. Các json()phương pháp chạm endpoint và người kia khẳng định là khá tự giải thích. Một chi tiết về assertJson(): phương thức này chuyển đổi phản hồi thành một mảng tìm kiếm đối số, vì vậy thứ tự là quan trọng. Bạn có thể xâu chuỗi nhiều assertJson() cuộc gọi trong trường hợp đó.

Bây giờ, hãy tạo bài kiểm tra điểm cuối đăng ký và viết một cặp cho điểm cuối đó:

$ php artisan make:test RegisterTest

Và cuối cùng, điểm cuối đăng xuất:

$ php artisan make:test LogoutTest

Điều quan trọng cần lưu ý là, trong quá trình thử nghiệm, ứng dụng Laravel không được khởi tạo lại theo yêu cầu mới. Điều đó có nghĩa là khi chúng ta nhấn phần mềm trung gian xác thực, nó sẽ lưu người dùng hiện tại bên trong TokenGuard thể hiện để tránh đánh lại cơ sở dữ liệu. Một lựa chọn khôn ngoan, tuy nhiên, trong trường hợp này, điều đó có nghĩa là chúng ta phải chia bài kiểm tra đăng xuất thành hai, để tránh mọi vấn đề với người dùng được lưu trong bộ nhớ cache trước đó.

Việc kiểm tra các điểm cuối của Điều cũng rất đơn giản:

Bước tiếp theo

Thats tất cả để có nó. Chắc chắn có cơ hội để cải thiện, bạn có thể triển khai OAuth2 với gói Passport , tích hợp lớp chuyển đổi và phân trang (tôi khuyên dùng Fractal), danh sách này có trên nhưng tôi muốn tìm hiểu những điều cơ bản về tạo và thử nghiệm API trong Laravel mà không cần gói bên ngoài.

Laravel chắc chắn đã cải thiện trải nghiệm của tôi với PHP và việc dễ dàng thử nghiệm với nó đã củng cố mối quan tâm của tôi đối với khung công tác. Nó không hoàn hảo, nhưng nó đủ linh hoạt để cho phép bạn giải quyết các vấn đề của nó.

Nếu bạn đang thiết kế API công khai, hãy xem 5 Quy tắc vàng cho Thiết kế API web tuyệt vời .