AngularJS $ http และ $ ทรัพยากร


257

ฉันมีบริการทางเว็บบางอย่างที่ฉันต้องการโทร $resourceหรือ$httpฉันควรใช้อันไหนดี?

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

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

หลังจากฉันอ่านหน้า API ทั้งสองด้านบนแล้วฉันก็หลงทาง

คุณกรุณาอธิบายให้ฉันฟังเป็นภาษาอังกฤษธรรมดาอะไรคือความแตกต่างและในสถานการณ์ใดที่ฉันควรใช้ ฉันจะจัดโครงสร้างการเรียกเหล่านี้และอ่านผลลัพธ์ลงในวัตถุ js อย่างถูกต้องได้อย่างไร


25
$ resource ถูกสร้างขึ้นจาก $ http และให้สิ่งที่เป็นนามธรรมเพิ่มเติมจากการสื่อสารพื้นฐาน มันต้องการจุดสิ้นสุด REST ที่สอดคล้องกับรูปแบบทรัพยากร $ เมื่อคุณถามข้อเสนอแนะของฉันคือเริ่มต้นด้วย $ http ทำความคุ้นเคยและต่อมาดูว่าคุณสามารถเปลี่ยนเป็น $ resource ได้หรือไม่
David Riccitelli

4
ขอบคุณสำหรับคำตอบ. ดังนั้นในสิ่งที่สถานการณ์เป็น $ http เคยต้องการมากกว่า $ ทรัพยากรนอกเหนือจากที่ฉันสามารถทำความคุ้นเคยกับ API?
Tom

คำตอบ:


168

$httpสำหรับ AJAX เพื่อวัตถุประสงค์ทั่วไป ในกรณีส่วนใหญ่นี่คือสิ่งที่คุณจะใช้ กับ$httpที่คุณกำลังจะได้รับการGET, POST, DELETEประเภทเรียกตนเองและการประมวลผลวัตถุพวกเขากลับมาด้วยตัวคุณเอง

$resourcewraps $httpสำหรับใช้ในสถานการณ์ RESTful web API


พูดมากโดยทั่วไป: บริการเว็บสงบจะได้รับการบริการที่มีหนึ่งปลายทางสำหรับชนิดข้อมูลที่ไม่สิ่งที่แตกต่างกับชนิดข้อมูลว่าขึ้นอยู่กับวิธีการ HTTP ชอบGET, POST, PUT, DELETEฯลฯ ดังนั้นด้วย$resourceคุณสามารถเรียกGETที่จะได้รับทรัพยากร เป็นวัตถุ JavaScript แล้วแก้ไขและส่งกลับมาพร้อมกับหรือแม้แต่ลบมันด้วยPOSTDELETE

... ถ้านั่นสมเหตุสมผล


1
ดังนั้นทรัพยากร $ จัดการกับบริการที่สงบซึ่งหมายความว่ามันสามารถใช้เรียกบริการเว็บปกติได้เช่นกัน เนื่องจากมันได้รับ POST DELETE PUT ทั้งหมดนั้น ดังนั้นในสถานการณ์ใดที่ $ http เคยนิยมมากกว่า $ resource?
Tom

7
ทุกเวลาจริง ๆ คุณไม่ได้จัดการกับจุดสิ้นสุดที่สงบสุขอย่างแท้จริง มันเพิ่มฟังก์ชั่นมากมายที่คุณไม่ต้องการหากปลายทางของคุณอนุญาตให้ใช้ GET เท่านั้น
เบ็นเลช

@blesh เพื่อใช้$resourceบริการก็จะเป็นแค่สำนวน / ดีถ้า REST ปลายทางของคุณสนับสนุนGET, POST, และ DELETE ? เอกสาร ( docs.angularjs.org/api/ngResource.$resource ) แสดงให้เห็นว่าคุณจะได้รับทั้ง 3 $resourceวิธีการส่วนที่เหลือด้วย
เควินเมเรดิ ธ

9
@KevinMeredith: หรือวิธีการใด ๆ ก็ได้ คุณสามารถเพิ่มPUTหรืออะไรก็ได้ที่คุณต้องการGET, POSTและDELETEเป็นเพียงค่าเริ่มต้น หากคุณมีจุดปลายที่เกี่ยวข้องกับทรัพยากรเดียวกัน (สำคัญมาก) สำหรับวิธี HTTP มากกว่าหนึ่งวิธี$resourceนั่นเป็นตัวเลือกที่ดี
เบ็นเลช

แม้จะเป็นจุดสิ้นสุดที่ไม่มีการพักสงบฉันก็พบว่ามันสะดวกที่จะใช้ $ resource สำหรับข้อมูลประเภท GET และ QUERY ให้วิธีการ.$promiseทำงานที่ดีresolveสำหรับการกำหนดเส้นทางและผูกพัน
Kevin

210

ผมรู้สึกว่าคำตอบอื่น ๆ ในขณะที่ถูกต้องค่อนข้างไม่อธิบายรากของคำถาม: เป็นส่วนหนึ่งของREST HTTPทุกอย่างที่นี้หมายถึงว่าสามารถทำได้ผ่านทางRESTสามารถทำได้ผ่านทางHTTPแต่ไม่ทุกอย่างที่สามารถทำได้ผ่านทางสามารถทำได้ผ่านทางHTTP RESTนั่นคือเหตุผลที่$resourceใช้$httpภายใน

ดังนั้นเมื่อใดควรใช้ซึ่งกันและกัน

หากทั้งหมดที่คุณต้องการคือRESTคุณกำลังพยายามเข้าถึงRESTfulเว็บเซอร์$resourceจะทำให้การโต้ตอบกับเว็บเซอร์นั้นเป็นเรื่องง่าย

แต่ถ้าคุณกำลังพยายามที่จะเข้าถึงทุกสิ่งที่ไม่ได้เป็นเว็บเซอร์ที่คุณกำลังจะต้องไปกับRESTful $httpเก็บไว้ในใจคุณยังสามารถเข้าถึงRESTfulเว็บเซอร์ผ่านมันก็จะยุ่งยากมากขึ้นกว่าที่มี$http $resourceนี่คือวิธีที่คนส่วนใหญ่ทำนอก AngularJS โดยใช้jQuery.ajax(เทียบเท่ากับ Angular's $http)


21
คำตอบที่ดีควรได้รับการยอมรับไม่ใช่ด้านบน
Andrzej Rehmann

2
หมายความว่าเรามีสามวิธีในการโทรหา RESTful ?? ใช้ $ resource, $ http และ jquery.ajax ใช่ไหม
Jake Huang

4
@ JakeHuang คุณสามารถโทรหามันได้แม้ไม่มีห้องสมุดใด ๆ ฉันเพิ่งเปิดเผย 2 แนวทางที่ได้รับความนิยมมากที่สุดในโลกของ AngularJS และวิธีที่พบมากที่สุดนอกเหนือจากนั้น
bluehallu

ฉันขอทราบว่า 2 แนวทางยอดนิยมใน AngularJS คืออะไร? : p
Jake Huang

41

$httpทำให้การโทร AJAX สำหรับวัตถุประสงค์ทั่วไปซึ่งโดยทั่วไปหมายถึงสามารถรวมAPE RESTfulและNon-RESTful API

และ$resourceเป็นผู้เชี่ยวชาญสำหรับสงบส่วนที่

Api ที่พักผ่อนได้ได้มาแพร่หลายในช่วงไม่กี่ปีที่ผ่านมาเนื่องจากมีการจัดระเบียบ URL ที่ดีขึ้นแทนที่จะเป็น URL แบบสุ่มที่เขียนขึ้นโดยโปรแกรมเมอร์

ถ้าฉันใช้RESTful APIเพื่อสร้าง URL มันจะเป็นอย่างไร/api/cars/:carIdก็จะเป็นสิ่งที่ชอบ

$resource วิธีดึงข้อมูล

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

    }]);

นี้จะทำให้คุณมีวัตถุทรัพยากรซึ่งจะมาพร้อมกับget, save, query, remove,deleteวิธีการโดยอัตโนมัติ

$http วิธีดึงข้อมูล

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

ดูว่าเราจำเป็นต้องกำหนดการดำเนินการทั่วไปในRESTFul APIอย่างไร อีกอย่างหนึ่งที่แตกต่างคือ$httpผลตอบแทนpromiseในขณะที่$resourceส่งกลับวัตถุ นอกจากนี้ยังมีปลั๊กอินบุคคลที่สามเพื่อช่วยจัดการ Angular กับRESTFul APIเช่นเป็นรูปสี่เหลี่ยมผืนผ้า


หาก API /api/getcarsinfoเป็นสิ่งที่ต้องการ $httpซ้ายทั้งหมดสำหรับเราคือการใช้งาน


4
นี่ควรเป็นผู้ตอบ
Royi Namir

1
หาก api คือ/api/getcarsinfoฉันเดาว่าเรายังคงสามารถใช้งานได้$resource
kittu

1
นี่ควรเป็นผู้ตอบ เมื่อคุณพูดว่า "สิ่งหนึ่งที่แตกต่างคือ $ http ส่งคืนสัญญาในขณะที่ $ resource ส่งคืนวัตถุ" 1- หมายความว่าฉันไม่จำเป็นต้องใช้แล้วกับ $ resource? 2- ในฐานะส่วนหน้าและนี่อาจฟังดูไร้สาระฉันจะรู้ได้อย่างไรว่า api นั้นสงบหรือไม่? ขอบคุณ
shireef khatab

1
@shireefkhatab 1. ใช่ $ resource เป็นเพียงนามธรรมในระดับที่สูงขึ้นของ $ http สำหรับการติดต่อสื่อสาร RESTFul API doc ตัวอย่างแสดงให้เห็นถึงวิธีการใช้งาน 2. มันขึ้นอยู่กับว่าแบ็กเอนด์ของคุณออกแบบ url อย่างไร หากเขาต้องการที่จะปฏิบัติตามกระบวนทัศน์ RESTFul api คุณก็พร้อมที่จะไป
Qiang

30

ฉันคิดว่าคำตอบนั้นขึ้นอยู่กับว่าคุณเป็นใครในเวลาที่คุณเขียนโค้ด ใช้หากคุณกำลังใหม่เพื่อเชิงมุมจนกว่าคุณจะรู้ว่าทำไมคุณต้อง$http $resourceจนกว่าคุณจะมีประสบการณ์ที่เป็นรูปธรรมของวิธีการที่$httpจะถือคุณกลับและคุณเข้าใจความหมายของการใช้$resourceในรหัสของคุณ$httpติดกับ

นี่เป็นประสบการณ์ของฉัน: ฉันเริ่มต้นโครงการเชิงมุมครั้งแรกของฉันฉันต้องทำการร้องขอ HTTP ไปยังอินเทอร์เฟซ RESTful ดังนั้นฉันจึงทำวิจัยเดียวกับที่คุณทำอยู่ตอนนี้ ขึ้นอยู่กับการอภิปรายผมอ่านในคำถาม SO $resourceเช่นนี้ผมเลือกที่จะไปกับ นี่เป็นความผิดพลาดที่ฉันหวังว่าจะทำได้ นี่คือเหตุผล:

  1. $httpตัวอย่างมีมากมายมีประโยชน์และโดยทั่วไปคือสิ่งที่คุณต้องการ $resourceตัวอย่างที่ชัดเจนนั้นหายากและ (จากประสบการณ์ของฉัน) แทบทุกสิ่งที่คุณต้องการ สำหรับมือใหม่คุณจะไม่ตระหนักถึงความหมายของตัวเลือกของคุณจนกระทั่งต่อมาเมื่อคุณสับสนกับเอกสารและโกรธที่คุณไม่สามารถหา$resourceตัวอย่างที่เป็นประโยชน์เพื่อช่วยเหลือคุณได้
  2. $httpอาจเป็นแผนที่จิตแบบ 1 ต่อ 1 กับสิ่งที่คุณกำลังมองหา $httpคุณไม่จำเป็นต้องเรียนรู้แนวคิดใหม่ที่จะเข้าใจสิ่งที่คุณได้รับ $resourceนำมาซึ่งความแตกต่างมากมายที่คุณยังไม่มีแผนที่ความคิด
  3. อุ๊ปส์ฉันว่าคุณไม่ต้องเรียนรู้แนวคิดใหม่หรือไม่? ในฐานะที่เป็นมือใหม่เชิงมุมคุณไม่ต้องเรียนรู้เกี่ยวกับสัญญา $httpส่งคืนสัญญาและ.thenสามารถทำได้ดังนั้นจึงเหมาะสมกับสิ่งใหม่ ๆ ที่คุณเรียนรู้เกี่ยวกับ Angular และสัญญา $resourceซึ่งไม่ได้คืนสัญญาโดยตรงทำให้การเข้าใจพื้นฐานเบื้องต้นของคุณซับซ้อนขึ้น
  4. $resourceมีประสิทธิภาพเพราะมันรวมรหัสสำหรับการโทร CRUD ที่สงบและการแปลงสำหรับอินพุตและเอาต์พุต ดีมากถ้าคุณเบื่อที่จะเขียนโค้ดซ้ำ ๆ เพื่อประมวลผลผลลัพธ์ของ$httpคุณเอง ให้คนอื่น$resourceเพิ่มเลเยอร์ความลับของไวยากรณ์และพารามิเตอร์ผ่านที่ทำให้เกิดความสับสน

ฉันหวังว่าฉันรู้จักฉัน 3 เดือนที่ผ่านมาและฉันจะบอกตัวเองอย่างเด่นชัด: "ติดกับ$httpเด็กมันไม่เป็นไร"


1
ฉันชอบคำตอบของคุณโดยเฉพาะบรรทัดสุดท้าย ขณะนี้ฉันกำลังเปลี่ยนผ่านการใช้ $ resource เทียบกับ $ http สิ่งหนึ่งที่ฉันยังต้องการเพิ่มคือ $ ทรัพยากรจริงๆเท่านั้นมามีประโยชน์จริงๆและจริงจะช่วยให้เมื่อคุณกำลังใช้ API เดียวกันคำนามเช่นหรือ/user/:userId /thingเมื่อคุณย้ายไป/users/roles/:roleIdแล้วคุณจะต้องแก้ไข $ resource url และ params ตามคำกริยาและคุณอาจใช้ $ http ในจุดนั้น
coblr

3
โทรหาฉันจิตเภทเพื่อแสดงความคิดเห็นคำตอบของฉันเอง แต่ฉันคิดว่าฉันจะพูดถึงประสบการณ์ที่ผ่านมามากขึ้น ฉันได้ทำการปรับโครงสร้างใหม่เพื่อกำจัด$resourceและเปลี่ยนไปใช้$httpในที่ต่างๆ ฉันไม่สามารถเน้นพอเท่าใดฉันปรารถนาปรารถนาความปรารถนาของ$resourceฉันไม่เคยพบ ฉันอาจเสียเวลามากกว่าหนึ่งสัปดาห์ในการไล่ตามความแตกต่างของ$resourceเดือนต่างๆ $httpเป็นเรื่องง่ายและตรงไปตรงมาการได้รับผลประโยชน์ใด ๆ นั้น$resourceถูกลบล้างโดยเส้นโค้งการเรียนรู้
Matthew Marichiba

24

ฉันคิดว่ามันเป็นสิ่งสำคัญที่จะเน้นว่าทรัพยากร $ คาดว่าวัตถุหรืออาร์เรย์เป็นการตอบสนองจากเซิร์ฟเวอร์ไม่ใช่สตริงดิบ ดังนั้นหากคุณมีสตริงดิบ (หรืออะไรก็ตามยกเว้นวัตถุและอาร์เรย์) เป็นการตอบสนองคุณต้องใช้ $ http


หมายความว่า $ http ไม่รองรับวัตถุและอาร์เรย์หรือไม่ แค่อยากจะชี้แจง
Shardul

ฉันเชื่อว่า $ http รองรับวัตถุอาร์เรย์และสตริง - ฉันต้องการการยืนยันว่า
Katana24

@Shardul ฉันเข้าใจว่า $ http จัดการกับการตอบสนองใด ๆ แต่ $ ข้อเสนอทรัพยากรกับวัตถุและอาร์เรย์เท่านั้น
shireef khatab

ไม่เป็นความจริงคุณยังสามารถใช้ $ resource เพื่อส่งคืนสตริง ใช้ 'transformResponse' ในรหัสส่วนหน้าของคุณเพื่อตัดสตริงที่ส่งคืนในวัตถุ
เทอร์รี่เติ้ง

7

เมื่อพูดถึงการเลือกระหว่าง$httpหรือ$resourceพูดเทคนิคไม่มีคำตอบที่ถูกหรือผิดในสาระสำคัญทั้งสองจะทำแบบเดียวกัน

วัตถุประสงค์$resourceคือเพื่อให้คุณสามารถส่งผ่านสตริงเทมเพลต (สตริงที่มีตัวยึดตำแหน่ง) พร้อมกับค่าพารามิเตอร์ $resourceจะแทนที่ตัวยึดตำแหน่งจากสตริงแม่แบบด้วยค่าพารามิเตอร์ที่ถูกส่งผ่านเป็นวัตถุ สิ่งนี้มีประโยชน์ส่วนใหญ่เมื่อโต้ตอบกับแหล่งข้อมูล RESTFul เนื่องจากใช้หลักการที่คล้ายกันเพื่อกำหนด URL

สิ่งที่$httpต้องดำเนินการกับคำขอ HTTP แบบอะซิงโครนัส


1
นี่เป็นคำตอบที่ดีเพราะชี้ให้เห็นว่า $ http เป็นสิ่งที่ขับเคลื่อนการร้องขอจาก $ resource และนั่นก็เป็นสิ่งเดียวกัน
coblr

@Dalorzo คุณหมายความว่าจะพูดว่า$resourceไม่สามารถทำงานแบบอะซิงโครนัสได้หรือไม่? แค่อยากจะอธิบาย
kittu

ไม่สิ่งที่ฉันชี้ให้เห็นก็คือในตอนท้าย$httpเป็นวิธีที่ง่ายที่สุดในการดำเนินการคำขอ HTTP แบบอะซิงโครนัสและสิ่งที่$resourceทำเช่นเดียวกัน แต่มีพารามิเตอร์ที่แตกต่างกัน
Dalorzo

2

บริการด้านทรัพยากรเป็นเพียงบริการที่มีประโยชน์สำหรับการทำงานกับ REST APSIs เมื่อคุณใช้มันคุณจะไม่เขียนวิธี CRUD ของคุณ (สร้างอ่านอัปเดตและลบ)

เท่าที่ฉันเห็นบริการทรัพยากรเป็นเพียงทางลัดคุณสามารถทำอะไรกับบริการ http


ฉันไม่แน่ใจว่าฉันจะจัดประเภททรัพยากร $ เป็นทางลัด มันเป็นเสื้อคลุมสำหรับ $ http ดังนั้นการใช้ $ http โดยตรงจะเป็น "สั้นกว่า" เป็นวิธีที่คุณสามารถกำหนดค่า $ http เพื่อให้คุณมีรหัสน้อยลงเมื่อใช้ $ http ในกรณีหนึ่ง$http.get('/path/to/thing', params)เมื่อเทียบกับบวกทำจริงการกำหนดค่าสำหรับmyResource.get(params) myResourceโค้ดเพิ่มเติมล่วงหน้าและใช้ได้เฉพาะกับนาม API เดียวกันเท่านั้น มิฉะนั้นคุณจะเขียนโค้ดเหมือนกับที่คุณใช้ $ http
coblr

2

สิ่งหนึ่งที่ฉันสังเกตเห็นเมื่อใช้ทรัพยากร $ มากกว่า $ http คือถ้าคุณใช้ Web API ใน. net

$ resource ถูกผูกเข้ากับคอนโทรลเลอร์หนึ่งตัวที่ดำเนินการเพื่อวัตถุประสงค์เดียว

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

ในขณะที่ $ http อาจเป็นอะไรก็ได้ เพียงระบุ URL

$ http.get - "api / รับรองความถูกต้อง"

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

มันเป็นเพียงความคิดเห็นของฉัน


0

บริการ $ resource ในปัจจุบันไม่สนับสนุนสัญญาดังนั้นจึงมีส่วนต่อประสานที่แตกต่างกันอย่างชัดเจนไปยังบริการ $ http


1
บริการ $ resource รองรับสัญญา แต่ไม่ส่งคืนสัญญา $ โดยตรงเช่น $ http ทำ ที่คุณต้องทำมันเหมือนvar myResource = $resource(...config...);แล้วที่อื่นในการให้บริการที่คุณทำreturn myResource.get(..params...)หรือคุณสามารถทำvar save = myResource.save(); save.$promise.then(...fn...); return save;
coblr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.