AngularJS $ http và $ resource


257

Tôi có một số dịch vụ web mà tôi muốn gọi. $resourcehoặc $http, tôi nên sử dụng cái nào?

$resource: https://docs.angularjs.org/api/ngResource/service/$resource

$http: https://docs.angularjs.org/api/ng/service/$http

Sau khi tôi đọc hai trang API ở trên, tôi bị mất.

Bạn có thể vui lòng giải thích cho tôi bằng tiếng Anh đơn giản sự khác biệt và trong tình huống nào tôi nên sử dụng chúng? Làm cách nào để cấu trúc các cuộc gọi này và đọc kết quả vào các đối tượng js một cách chính xác?


25
$ resource được xây dựng dựa trên $ http và cung cấp sự trừu tượng hóa hơn nữa từ các liên lạc cơ bản. Nó cũng đòi hỏi một điểm cuối REST phù hợp với các mẫu tài nguyên $. Vì bạn đang hỏi, đề xuất của tôi là bắt đầu với $ http, làm quen và sau đó xem bạn có thể chuyển sang $ resource không.
David Riccitelli

4
Cảm ơn câu trả lời. Vì vậy, trong trường hợp nào $ http từng được ưu tiên hơn $ resource ngoài việc tôi có thể làm quen với api?
Tom

Câu trả lời:


168

$httpdành cho mục đích chung AJAX. Trong hầu hết các trường hợp, đây là những gì bạn sẽ sử dụng. Với việc $httpbạn sẽ thực hiện GET, POSThãy DELETEnhập các cuộc gọi theo cách thủ công và xử lý các đối tượng mà chúng tự trả về.

$resourcekết thúc tốt đẹp $httpđể sử dụng trong các kịch bản API web RESTful.


Phát biểu RẤT thường: dịch vụ web RESTful Một sẽ là một dịch vụ với một thiết bị đầu cuối cho một loại dữ liệu mà làm những việc khác nhau với kiểu dữ liệu dựa trên HTTP phương pháp thích GET, POST, PUT, DELETE, vv Vì vậy, với một $resource, bạn có thể gọi một GETđể có được những tài nguyên dưới dạng đối tượng JavaScript, sau đó thay đổi nó và gửi lại bằng a POSThoặc thậm chí xóa nó bằng DELETE.

... nếu điều đó hợp lý.


1
Vì vậy, $ resource xử lý các dịch vụ Restful, điều đó có nghĩa là nó cũng có thể được sử dụng để gọi các dịch vụ web thông thường? Vì nó NHẬN POST DEL DEL PUT tất cả những thứ đó. Vì vậy, trong trường hợp nào $ http từng được ưa thích hơn $ resource?
Tom

7
Thực sự bất cứ lúc nào bạn không đối phó với một điểm cuối thực sự yên tĩnh. Ví dụ, nó bổ sung rất nhiều chức năng mà bạn không cần nếu điểm cuối của bạn chỉ cho phép GET, chẳng hạn.
Ben Lesh

@blesh, vì vậy việc sử dụng $resourcedịch vụ sẽ chỉ là thành ngữ / tốt nếu bạn hỗ trợ REST của thiết bị đầu cuối GET, POST, DELETE ? Các tài liệu ( docs.angularjs.org/api/ngResource.$resource ) cho thấy rằng bạn có được 3 phương thức REST này với $resource.
Kevin Meredith

9
@KevinMeredith: Hoặc bất kỳ số phương thức nào. Bạn có thể thêm PUThoặc bất cứ thứ gì bạn thích GET, POSTDELETEchỉ là mặc định. Nếu bạn có một điểm cuối liên quan đến cùng một tài nguyên (điều đó quan trọng) cho nhiều hơn một phương thức HTTP, thì đó $resourcelà một lựa chọn tốt.
Ben Lesh

Ngay cả đối với điểm cuối không có RESTful, tôi vẫn thấy thuận tiện khi sử dụng $ resource cho dữ liệu loại GET và QUERY. Đưa ra cách .$promiselàm việc tốt resolveđể định tuyến và ràng buộc.
Kevin

210

Tôi cảm thấy rằng các câu trả lời khác, trong khi chính xác, không hoàn toàn giải thích gốc rễ của câu hỏi: RESTlà một tập hợp con của HTTP. Điều này có nghĩa là mọi thứ có thể được thực hiện thông qua RESTcó thể được thực hiện thông qua HTTPnhưng không phải mọi thứ có thể được thực hiện thông qua HTTPđều có thể được thực hiện thông qua REST. Đó là lý do tại sao $resourcesử dụng $httpnội bộ.

Vậy, khi nào nên sử dụng nhau?

Nếu tất cả những gì bạn cần là REST, đó là, bạn đang cố gắng truy cập một dịch vụ web RESTful,$resource sẽ giúp việc tương tác với dịch vụ web đó trở nên cực kỳ dễ dàng.

Thay vào đó, nếu bạn đang cố gắng truy cập BẤT CỨ điều gì không phải là dịch vụ web RESTful, bạn sẽ phải đi cùng $http. Hãy nhớ rằng, bạn cũng có thể truy cập một dịch vụ web RESTfulthông qua $http, nó sẽ cồng kềnh hơn nhiều so với $resource. Đây là cách mà hầu hết mọi người đã làm nó bên ngoài AngularJS, bằng cách sử dụng jQuery.ajax(tương đương với Angular $http).


21
câu trả lời hay, điều này nên được chấp nhận, không phải câu trả lời trên
Andrzej Rehmann

2
Nó có nghĩa là chúng ta có ba cách để gọi RESTful ?? Sử dụng $ resource, $ http và jquery.ajax, tôi có đúng không ??
Jake Huang

4
@JakeHuang Bạn có thể gọi nó ngay cả khi không có bất kỳ thư viện nào, có vô số cách để làm điều đó. Tôi chỉ tiếp xúc với 2 cách tiếp cận phổ biến nhất trong thế giới AngularJS và cách tiếp cận phổ biến nhất bên ngoài nó.
bluehallu 4/2/2015

Tôi có thể biết 2 cách tiếp cận phổ biến nhất trong AngularJS là gì không? : p
Jake Huang

41

$httpthực hiện cuộc gọi AJAX cho mục đích chung, trong đó chung có nghĩa là nó có thể bao gồm api RESTful cộng với api không RESTful .

$resourcelà chuyên ngành cho phần RESTful đó .

Api yên tĩnh đã trở nên thịnh hành trong những năm gần đây vì url được tổ chức tốt hơn thay vì url ngẫu nhiên được tạo bởi các lập trình viên.

Nếu tôi sử dụng API RESTful để tạo url, nó sẽ giống như thế /api/cars/:carId.

$resource cách để lấy dữ liệu

angular.module('myApp', ['ngResource'])

    // Service
    .factory('FooService', ['$resource', function($resource) {
        return $resource('/api/cars/:carId')
    }]);

    // Controller
    .controller('MainController', ['FooService', function(FooService){
        var self = this;
        self.cars = FooService.query();
        self.myCar = FooService.get('123');

    }]);

Điều này sẽ cung cấp cho bạn một đối tượng tài nguyên , mà được đi kèm với get, save, query, remove, deletephương pháp tự động.

$http cách để lấy dữ liệu

angular.module('myApp', [])

    // Service
    .factory('FooService', ['$http', function($http){
        return {
            query: function(){
                return $http.get('/api/cars');
            },

            get: function(){
                return $http.get('/api/cars/123');
            }
            // etc...
        }

Xem cách chúng tôi cần xác định từng thao tác phổ biến trên API RESTFul . Ngoài ra một sự khác biệt là $httptrả về promisetrong khi $resourcetrả về một đối tượng. Ngoài ra còn có các plugin của bên thứ ba để giúp Angular đối phó với API RESTFul như restangular


Nếu API là một cái gì đó như /api/getcarsinfo. Tất cả còn lại cho chúng tôi là để sử dụng $http.


4
Đây phải là người trả lời.
Royi Namir

1
Nếu api là /api/getcarsinfotôi đoán chúng ta vẫn có thể sử dụng$resource
kittu

1
Đây phải là người trả lời. khi bạn nói "Ngoài ra, một điểm khác biệt là $ http trả lại lời hứa trong khi $ resource trả về một đối tượng" 1- điều đó có nghĩa là tôi không cần sử dụng .then với $ resource? 2- cũng là một người ở lối vào và điều này nghe có vẻ ngớ ngẩn làm thế nào tôi có thể tìm ra nếu api có yên tĩnh hay không? cảm ơn
shireef khatab

1
@shireefkhatab 1. có, $ resource chỉ là mức độ trừu tượng hóa cao hơn của $ http cho sự kết hợp API RESTFul. Các doc ví dụ cho thấy cách sử dụng nó. 2. Nó hoàn toàn phụ thuộc vào cách anh chàng phụ trợ của bạn thiết kế url. Nếu anh ấy muốn tuân thủ mô hình api RESTFul, thì bạn nên đi
Qiang

30

Tôi nghĩ rằng câu trả lời phụ thuộc nhiều hơn vào bạn là ai tại thời điểm bạn viết mã. Sử dụng $httpnếu bạn chưa quen với Angular, cho đến khi bạn biết lý do tại sao bạn cần $resource. Cho đến khi bạn có kinh nghiệm cụ thể như thế nào $httpđược giữ lại cho bạn, và bạn hiểu được ý nghĩa của việc sử dụng $resourcetrong mã của bạn , dính với $http.

Đây là kinh nghiệm của tôi: Tôi đã bắt đầu dự án Angular đầu tiên của mình, tôi cần thực hiện các yêu cầu HTTP đến giao diện RESTful, vì vậy tôi đã thực hiện cùng một nghiên cứu mà bạn đang thực hiện. Dựa trên cuộc thảo luận tôi đọc trong các câu hỏi SO như thế này, tôi đã chọn đi cùng $resource. Đây là một sai lầm tôi ước tôi có thể hoàn tác. Đây là lý do tại sao:

  1. $httpví dụ rất phong phú, hữu ích và nói chung chỉ là những gì bạn cần. Các $resourceví dụ rõ ràng là khan hiếm, và (theo kinh nghiệm của tôi) hiếm khi mọi thứ bạn cần. Đối với người mới chơi Angular, bạn sẽ không nhận ra ý nghĩa của lựa chọn của mình cho đến sau này, khi bạn băn khoăn về tài liệu và tức giận rằng bạn không thể tìm thấy các $resourceví dụ hữu ích để giúp bạn.
  2. $httpcó lẽ là bản đồ tinh thần 1-1 đối với những gì bạn đang tìm kiếm. Bạn không cần phải học một khái niệm mới để hiểu những gì bạn nhận được $http. $resourcemang theo rất nhiều sắc thái mà bạn chưa có bản đồ tinh thần nào.
  3. Rất tiếc, tôi có nói bạn không phải học một khái niệm mới không? Như một newbie Góc bạn làm phải tìm hiểu về những lời hứa. $httptrả lại một lời hứa và .thencó thể, vì vậy nó phù hợp với những điều mới mà bạn đang tìm hiểu về Angular và những lời hứa. $resource, không trả lại lời hứa trực tiếp, làm phức tạp sự nắm bắt dự kiến ​​của bạn về các nguyên tắc cơ bản của Angular.
  4. $resourcelà mạnh mẽ bởi vì nó ngưng tụ mã cho các cuộc gọi CRUD RESTful và các biến đổi cho đầu vào và đầu ra. Thật tuyệt nếu bạn phát ốm vì liên tục viết mã để xử lý kết quả của $httpchính mình. Đối với bất kỳ ai khác, $resourcethêm một lớp cú pháp và tham số khó hiểu đi qua gây nhầm lẫn.

Tôi ước tôi biết tôi 3 tháng trước, và tôi sẽ tự nhủ với chính mình: "Hãy gắn bó với $httpđứa trẻ. Nó vẫn ổn."


1
Tôi thích câu trả lời của bạn, đặc biệt là dòng cuối cùng. Tôi hiện đang trải qua một sự thay đổi trong việc sử dụng $ resource so với $ http. Một điều tôi cũng muốn nói thêm là $ resource thực sự chỉ thực sự tiện dụng và thực sự hữu ích khi bạn đang sử dụng cùng một danh từ API , như /user/:userIdhoặc /thing. Khi bạn chuyển đến /users/roles/:roleIdthì bạn phải sửa đổi url tài nguyên và thông số $ trên cơ sở mỗi động từ và bạn cũng có thể sử dụng $ http tại thời điểm đó.
coblr

3
Gọi tôi là tâm thần phân liệt để bình luận về câu trả lời của riêng tôi, nhưng tôi nghĩ tôi sẽ đề cập đến nhiều kinh nghiệm gần đây. Tôi đã được tái cấu trúc để loại bỏ $resourcevà chuyển sang $httpnơi. Tôi không thể nhấn mạnh đủ bao nhiêu tôi ước điều ước ước tôi chưa bao giờ gặp $resource. Tôi có lẽ đã lãng phí hơn một tuần để theo đuổi các sắc thái của $resourcenhững tháng qua. $httprất dễ dàng và đơn giản, bất kỳ lợi ích nào có $resourceđược đã bị xóa sạch hoàn toàn bởi đường cong học tập.
Matthew Marichiba

24

Tôi nghĩ điều quan trọng là phải nhấn mạnh rằng $ resource mong đợi đối tượng hoặc mảng là phản hồi từ máy chủ, chứ không phải chuỗi thô. Vì vậy, nếu bạn có chuỗi thô (hoặc bất cứ thứ gì ngoại trừ đối tượng và mảng) làm phản hồi, bạn phải sử dụng $ http


Điều đó có nghĩa là $ http không hỗ trợ đối tượng và mảng? Chỉ muốn làm rõ.
Shardul

Tôi tin rằng $ http hỗ trợ các đối tượng, mảng và chuỗi - mặc dù tôi cần xác nhận về điều đó
Katana24

@Shardul, tôi hiểu rằng $ http chỉ giao dịch với bất kỳ loại phản hồi nào nhưng $ chỉ giao dịch với các đối tượng và mảng.
shireef khatab

Không đúng, bạn vẫn có thể sử dụng $ resource để trả về Chuỗi. Sử dụng 'TransformResponse' trong mã frontend của bạn để bọc Chuỗi trả về trong một đối tượng.
Terry Đặng

7

Khi nói đến việc lựa chọn giữa $httphoặc $resourcenói về mặt kỹ thuật, không có câu trả lời đúng hay sai về bản chất cả hai sẽ làm như vậy.

Mục đích của $resourceviệc cho phép bạn truyền vào một chuỗi mẫu (một chuỗi chứa chỗ dành sẵn) cùng với các giá trị tham số. $resourcesẽ thay thế các trình giữ chỗ từ chuỗi mẫu bằng các giá trị tham số được truyền dưới dạng đối tượng. Điều này chủ yếu hữu ích khi tương tác với nguồn dữ liệu RESTFul vì chúng sử dụng các nguyên tắc tương tự để xác định URL.

Điều gì $httplàm là thực hiện các Yêu cầu HTTP không đồng bộ.


1
Đây là một câu trả lời tốt bởi vì nó chỉ ra rằng $ http là thứ cung cấp năng lượng cho các yêu cầu từ $ resource và về cơ bản là thực hiện cùng một thứ.
coblr

@Dalorzo Vậy ý bạn là $resourcekhông thể thực hiện Không đồng bộ? Chỉ muốn làm rõ
kittu

Không, điều tôi đã chỉ ra là cuối cùng $httplà cách đơn giản nhất để thực hiện Yêu cầu HTTP không đồng bộ và về $resourcecơ bản là giống nhau nhưng với các tham số khác nhau
Dalorzo

2

dịch vụ tài nguyên chỉ là dịch vụ hữu ích để làm việc với REST APSIs. Khi bạn sử dụng, bạn không viết các phương thức CRUD của mình (tạo, đọc, cập nhật và xóa)

Theo tôi thấy, dịch vụ tài nguyên chỉ là một phím tắt, bạn có thể làm bất cứ điều gì với dịch vụ http.


Tôi không chắc chắn tôi sẽ phân loại $ resource là một phím tắt. Đó là một trình bao bọc cho $ http, vì vậy sử dụng trực tiếp $ http sẽ "ngắn hơn". Đây là cách để bạn định cấu hình $ http để bạn có khả năng ít mã hơn khi sử dụng $ http. Trong một trường hợp $http.get('/path/to/thing', params)so với myResource.get(params)cộng thực sự làm cấu hình cho myResource. Nhiều mã hơn ở phía trước và chỉ thực sự hoạt động một cách bơi lội với cùng một danh từ API. Mặt khác, bạn đang mã hóa nhiều như thể bạn đã sử dụng $ http.
coblr

2

Một điều tôi nhận thấy khi sử dụng $ resource trên $ http là nếu bạn đang sử dụng API Web trong .net

$ resource được gắn vào một bộ điều khiển thực thi một mục đích duy nhất.

$ resource ('/ user /: userId', {userId: '@ id'});

[HttpGet]
public bool Get(int id)
{
    return "value"
}

public void Post([FromBody]string value)
{
}

public void Put(int id, [FromBody]string value)
{
}

public void Delete(int id)
{
}

Trong khi $ http có thể là bất cứ điều gì. chỉ cần xác định url.

$ http.get - "api / xác thực"

[HttpGet]
public bool Authenticate(string email, string password)
{
    return _authenticationService.LogIn(email, password, false);
}

đó chỉ là ý kiến ​​của tôi


0

Dịch vụ $ resource hiện không hỗ trợ các lời hứa và do đó có giao diện khác biệt với dịch vụ $ http.


1
Dịch vụ $ resource không hỗ trợ các lời hứa, nhưng nó không trả lại lời hứa $ trực tiếp như $ http. Bạn phải làm như thế var myResource = $resource(...config...);sau đó ở một nơi khác trong dịch vụ bạn làm return myResource.get(..params...)hoặc bạn có thể làmvar save = myResource.save(); save.$promise.then(...fn...); return save;
coblr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.