AngularJS $ http et $ resource

257

J'ai quelques services Web que je veux appeler. $resourceou $httplequel dois-je utiliser?

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

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

Après avoir lu les deux pages API ci-dessus, je suis perdu.

Pourriez-vous s'il vous plaît m'expliquer en anglais simple quelle est la différence et dans quelle situation dois-je les utiliser? Comment structurer ces appels et lire correctement les résultats dans des objets js?

À M
la source
25
La ressource $ est construite au-dessus de $ http et fournit une abstraction supplémentaire des communications sous-jacentes. Il nécessite également un point de terminaison REST conforme aux modèles de ressource $. Puisque vous demandez, ma suggestion est de commencer par $ http, de vous familiariser, puis de voir plus tard si vous pouvez passer à $ resource.
David Riccitelli
4
Merci d'avoir répondu. Alors, dans quelle situation $ http est-il jamais préféré à $ resource, à part que je puisse me familiariser avec l'api?
Tom

Réponses:

168

$httpest à usage général AJAX. Dans la plupart des cas, c'est ce que vous utiliserez. Avec $httpvous allez faire GET, POST, le DELETEtype appelle manuellement et traiter les objets qu'ils reviennent sur votre propre.

$resourceencapsule $httpà utiliser dans les scénarios d'API Web RESTful.


De façon très générale: Un service Web RESTful sera un service avec un point final pour un type de données qui fait des choses différentes avec ce type de données basées sur des méthodes HTTP aiment GET, POST, PUT, DELETE, etc. Donc , avec un $resource, vous pouvez appeler GETpour obtenir la ressource en tant qu'objet JavaScript, puis modifiez-le et renvoyez-le avec un POST, ou même supprimez-le avec DELETE.

... si ça a du sens.

Ben Lesh
la source
1
Donc, $ resource gère les services Restful, cela signifie qu'il peut également être utilisé pour appeler des services Web normaux? Puisqu'il GET POST DELETE METTEZ tout cela. Alors, dans quelle situation $ http est-il jamais préféré à $ resource?
Tom
7
Vraiment chaque fois que vous ne traitez pas avec un point final vraiment reposant. Il ajoute de nombreuses fonctionnalités dont vous n'auriez pas besoin si votre point de terminaison autorisait uniquement GET, par exemple.
Ben Lesh
@blesh, donc l' utilisation du $resourceservice serait seulement idiomatiques / bien si vos supports d'extrémité REST GET, POST, et DELETE ? Les documents ( docs.angularjs.org/api/ngResource.$resource ) montrent que vous obtenez ces 3 méthodes REST avec $resource.
Kevin Meredith
9
@KevinMeredith: Ou c'est un nombre quelconque de méthodes. Vous pouvez ajouter PUTou tout ce que vous souhaitez GET, POSTet ne DELETEsont que des valeurs par défaut. Si vous avez un point de terminaison qui traite de la même ressource (ce qui est important) pour plusieurs méthodes HTTP, $resourcec'est un bon choix.
Ben Lesh
Même pour un point de terminaison sans RESTful, j'ai trouvé pratique d'utiliser $ resource pour les données de type GET et QUERY. Compte tenu de la façon dont le .$promisefonctionne bien resolvepour le routage et la liaison.
Kevin
210

Je pense que d'autres réponses, bien que correctes, n'expliquent pas tout à fait la racine de la question: RESTest un sous-ensemble de HTTP. Cela signifie que tout ce qui peut être fait via RESTpeut être fait via HTTPmais pas tout ce qui peut être fait via HTTPne peut pas être fait via REST. C'est pourquoi $resourceutilise en $httpinterne.

Alors, quand utiliser les uns les autres?

Si tout ce dont vous avez besoin REST, c'est que vous essayez d'accéder à un service RESTfulWeb, $resourcerendra l'interaction avec ce service Web très facile.

Si, à la place, vous essayez d'accéder à TOUT ce qui n'est pas un service RESTfulWeb, vous devrez y aller $http. Gardez à l'esprit que vous pouvez également accéder à un service RESTfulWeb via $http, il sera juste beaucoup plus lourd qu'avec $resource. C'est la façon dont la plupart des gens l'ont fait en dehors d'AngularJS, en utilisant jQuery.ajax(l'équivalent d'Angular $http).

Bluehallu
la source
21
belle réponse, cela devrait être accepté, pas celui du dessus
Andrzej Rehmann
2
Cela signifie que nous avons trois façons d'appeler RESTful ?? En utilisant $ resource, $ http et jquery.ajax, ai-je raison ??
Jake Huang
4
@JakeHuang Vous pouvez l'appeler même sans bibliothèque, il existe des façons infinies de le faire. Je viens d'exposer les 2 approches les plus populaires dans le monde AngularJS et l'approche la plus courante en dehors de celui-ci.
bluehallu
Puis-je savoir quelles sont les 2 approches les plus populaires dans AngularJS? : p
Jake Huang
41

$httpeffectue un appel AJAX à usage général, ce qui signifie généralement qu'il peut inclure une API RESTful plus une API non RESTful .

et $resourceest spécialisé pour cette partie RESTful .

Api reposant est devenu répandu ces dernières années parce que l'url est mieux organisée au lieu d'une URL aléatoire composée par des programmeurs.

Si j'utilise une API RESTful pour construire l'URL, ce serait quelque chose comme /api/cars/:carId.

$resource façon de récupérer des données

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');

    }]);

Cela vous donnera un objet ressource , qui est accompagné get, save, query, remove, deleteméthodes automatiquement.

$http façon de récupérer des données

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...
        }

Découvrez comment nous devons définir chaque opération commune sur l' API RESTFul . Une différence est également que $httprenvoie promisewhile $resourcerenvoie un objet. Il existe également des plugins tiers pour aider Angular à gérer l'API RESTFul comme restangular


Si l'API ressemble à quelque chose /api/getcarsinfo. Il ne nous reste plus qu'à utiliser $http.

Qiang
la source
4
Cela devrait être la réponse.
Royi Namir
1
Si l'api est, /api/getcarsinfoje suppose que nous pouvons toujours utiliser$resource
kittu
1
Cela devrait être la réponse. quand vous avez dit "Une autre différence est que $ http retourne une promesse tandis que $ resource retourne un objet" 1- cela signifie-t-il que je n'ai pas besoin d'utiliser .then avec $ resource? 2- également en tant que personne frontend et cela peut sembler idiot comment puis-je savoir si l'api est reposant ou non? merci
shireef khatab
1
@shireefkhatab 1. oui, $ resource n'est qu'une abstraction de niveau supérieur de $ http pour la connivence de l'API RESTFul. L' exemple de doc montre comment l'utiliser. 2. Cela dépend totalement de la façon dont votre backend conçoit l'url. S'il veut se conformer au paradigme de l'api RESTFul, alors vous êtes prêt à partir
Qiang
30

Je pense que la réponse dépend davantage de qui vous êtes au moment où vous écrivez le code. À utiliser $httpsi vous débutez avec Angular, jusqu'à ce que vous sachiez pourquoi vous en avez besoin $resource. Jusqu'à ce que vous ayez une expérience concrète de la façon dont $httpvous vous retenez et que vous compreniez les implications de l'utilisation $resourcedans votre code , restez avec $http.

Ce fut mon expérience: j'ai commencé mon premier projet Angular, j'avais besoin de faire des requêtes HTTP à une interface RESTful, donc j'ai fait la même recherche que vous faites maintenant. Sur la base de la discussion que j'ai lue dans des questions SO comme celle-ci, j'ai choisi d'y aller $resource. C'était une erreur que j'aurais aimé pouvoir annuler. Voici pourquoi:

  1. $httples exemples sont nombreux, utiles et généralement juste ce dont vous avez besoin. Les $resourceexemples clairs sont rares et (selon mon expérience) rarement tout ce dont vous avez besoin. Pour le débutant Angular, vous ne réaliserez les implications de votre choix que plus tard, lorsque vous serez coincé par la documentation et en colère de ne pas trouver d' $resourceexemples utiles pour vous aider.
  2. $httpest probablement une carte mentale 1 à 1 de ce que vous recherchez. Vous n'avez pas besoin d'apprendre un nouveau concept pour comprendre ce que vous obtenez $http.$resourceapporte beaucoup de nuances pour lesquelles vous n'avez pas encore de carte mentale.
  3. Oups, ai-je dit que vous n'avez pas à apprendre un nouveau concept? En tant que débutant angulaire vous ne devez en apprendre davantage sur les promesses. $httprenvoie une promesse et est .thencapable, donc il s'intègre parfaitement avec les nouvelles choses que vous apprenez sur Angular et les promesses. $resource, qui ne renvoie pas directement une promesse, complique votre compréhension provisoire des fondamentaux angulaires.
  4. $resourceest puissant car il condense le code des appels RESTful CRUD et les transformations d'entrée et de sortie. C'est génial si vous en avez marre d'écrire à plusieurs reprises du code pour traiter les résultats de $httpvous - même. Pour quelqu'un d'autre, $resourceajoute une couche cryptique de syntaxe et de passage de paramètres qui prête à confusion.

J'aimerais bien me connaître il y a 3 mois, et je me dirais avec emphase: "Reste avec l' $httpenfant. C'est très bien."

Matthew Marichiba
la source
1
J'aime ta réponse, surtout la dernière ligne. Je suis actuellement en train de changer l'utilisation de $ resource vs $ http. La seule chose que j'ajouterais également, c'est que $ resource n'est vraiment très utile et aide réellement que lorsque vous utilisez le même nom d' API , comme /user/:userIdou /thing. Une fois que vous passez à, /users/roles/:roleIdvous devez modifier l'URL et les paramètres de $ resource par verbe et vous pourriez tout aussi bien utiliser $ http à ce stade.
coblr
3
Appelez-moi schizophrène pour avoir commenté ma propre réponse, mais je pensais mentionner une expérience plus récente. J'ai refactorisé pour éliminer $resourceet passer à $httpcertains endroits. Je ne saurais trop insister sur le souhait que j'aurais souhaité n'avoir jamais rencontré $resource. J'ai probablement perdu plus d'une semaine à chasser les nuances de $resourceces derniers mois. $httpest si facile et simple, tout gain à gagner a $resourceété complètement effacé par la courbe d'apprentissage.
Matthew Marichiba
24

Je pense qu'il est important de souligner que $ resource attend l'objet ou le tableau comme réponse du serveur, pas une chaîne brute. Donc, si vous avez une chaîne brute (ou quoi que ce soit sauf un objet et un tableau) comme réponse, vous devez utiliser $ http

sparrkli
la source
Cela signifie-t-il que $ http ne prend pas en charge les objets et les tableaux? Je voulais juste clarifier.
Shardul
Je crois que $ http prend en charge les objets, les tableaux et les chaînes - j'aurais cependant besoin d'une confirmation à ce sujet
Katana24
@Shardul, j'ai compris que $ http traite de tout type de réponse mais que $ resource ne traite que des objets et des tableaux.
shireef khatab
Ce n'est pas vrai, vous pouvez toujours utiliser $ resource pour renvoyer une chaîne. Utilisez 'transformResponse' dans votre code frontal pour encapsuler la chaîne retournée dans un objet.
Terry Deng
7

Quand il s'agit de choisir entre $httpou $resourcetechniquement parlant, il n'y a pas de bonne ou de mauvaise réponse, les deux feront la même chose.

Le but de $resourceest de vous permettre de passer une chaîne de modèle (une chaîne qui contient des espaces réservés) avec les valeurs des paramètres. $resourceremplacera les espaces réservés de la chaîne de modèle par les valeurs de paramètre celles transmises en tant qu'objet. Cela est surtout utile lors de l'interaction avec la source de données RESTFul car ils utilisent des principes similaires pour définir les URL.

Qu'est $http- ce que c'est, c'est d'exécuter les requêtes HTTP asynchrones.

Dalorzo
la source
1
C'est une bonne réponse car elle souligne que $ http est ce qui alimente les requêtes de $ resource, et que l'une ou l'autre fait essentiellement la même chose.
coblr
@Dalorzo Donc, vous voulez dire que $resourcevous ne pouvez pas effectuer de manière asynchrone? Je voulais juste clarifier
kittu
Non, ce que j'ai souligné, c'est qu'à la fin $httpest le moyen le plus simple d'effectuer une demande HTTP asynchrone et ce qui fait $resourceessentiellement la même chose mais avec des paramètres différents
Dalorzo
2

le service de ressources est juste un service utile pour travailler avec les APSI REST. lorsque vous l'utilisez, vous n'écrivez pas vos méthodes CRUD (créer, lire, mettre à jour et supprimer)

Pour autant que je le vois, le service de ressources n'est qu'un raccourci, vous pouvez tout faire avec le service http.

John Smith
la source
Je ne suis pas sûr de classer $ resource comme raccourci. C'est un wrapper pour $ http, donc utiliser directement $ http serait "plus court". C'est un moyen pour vous de configurer $ http afin d'avoir potentiellement moins de code lors de l'utilisation de $ http. Dans un cas, $http.get('/path/to/thing', params)versus myResource.get(params)plus fait la configuration de myResource. Plus de code à l'avant et ne fonctionne vraiment que de manière fluide avec le même nom d'API. Sinon, vous codez autant que si vous utilisiez $ http.
coblr
2

Une chose que j'ai remarquée lors de l'utilisation de $ resource sur $ http est que vous utilisez l'API Web dans .net

$ resource est lié à un contrôleur qui exécute un seul objectif.

$ 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)
{
}

Alors que $ http pourrait être de n'importe quoi. spécifiez simplement l'URL.

$ http.get - "api / authenticate"

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

c'est juste mon avis.

jayson.centeno
la source
0

Le service $ resource actuellement ne prend pas en charge les promesses et a donc une interface distinctement différente du service $ http.

bizarre
la source
1
Le service $ resource prend en charge les promesses, mais il ne renvoie pas directement une promesse $ comme le fait $ http. Vous devez le faire comme var myResource = $resource(...config...);alors ailleurs dans le service que vous faites return myResource.get(..params...)ou vous pouvez fairevar save = myResource.save(); save.$promise.then(...fn...); return save;
coblr