使用PHP创建一个REST API(Create a REST API with PHP)
譯者前言:
首先這是一篇國(guó)外的英文文章,非常系統(tǒng)、詳盡的介紹了如何使用PHP創(chuàng)建REST API,國(guó)內(nèi)這方面的資料非常非常的有限,而且基本沒有可操作性。這篇文章寫的非常好,只要對(duì)PHP稍有了解的程序員,看完本文基本可以自己動(dòng)手寫 REST API,花了幾個(gè)小時(shí)翻譯過(guò)來(lái)和大家共享,希望可以幫助大家。轉(zhuǎn)載請(qǐng)注明出處。
本文地址:http://hmw.iteye.com/blog/1190827
原文地址:Create a REST API with PHP
One of the latest (sort of) crazes sweeping the net is APIs, more specifically those that leverage REST. It’s really no surprise either, as consuming REST APIs is so incredibly easy… in any language. It’s also incredibly easy to create them as you essentially use nothing more than an HTTP spec that has existed for ages. One of the few things that I give Rails credit for is its well thought-out REST support, both for providing and consuming these APIs (as its been explained by all the Rails fanboys I work with).
最近互聯(lián)網(wǎng)上比較熱門的一個(gè)名詞是APIs(接口),特別是leverage REST。不過(guò)考慮到REST APIs在任何語(yǔ)言下都是非常的簡(jiǎn)單,也就沒什么好驚奇的了。同時(shí),它也是非常的容易創(chuàng)建,你基本只需要使用已經(jīng)存在多年的HTTP規(guī)范就可以。我認(rèn)為 Rails語(yǔ)言的為數(shù)不多的優(yōu)點(diǎn)之一就是良好的REST支持,不僅是提供APIs,同時(shí)也有很多的客戶端支持(我的一些Rails粉絲同事都向我解釋了這 一點(diǎn))。
Seriously, if you’ve never used REST, but you’ve ever had to work with (or worse, create) a SOAP API, or simply opened a WSDL and had your head explode, boy do I have good news for you!
認(rèn)真的講,假如你從來(lái)沒有使用過(guò)REST,卻曾經(jīng)使用過(guò)SOAP API,或者只是簡(jiǎn)單的打開一個(gè)令人頭大的WSDL文檔。小伙子,我確實(shí)要帶給你一個(gè)好消息!
So, What on Earth is REST? Why Should You Care?
那么,究竟什么是REST?為什么你應(yīng)該關(guān)心?
Before we get into writing some code, I want to make sure everyone’s got a good understanding of what REST is and how its great for APIs. First, technically speaking, REST isn’t specific to just APIs, it’s more of a generic concept. However, obviously, for the sake of this article we’ll be talking about it in the context of an API. So, let’s look at the basic needs of an API and how REST addresses them.
在我們開始寫代碼之前,我想要確認(rèn)每個(gè)人都可以很好的理解什么是REST以及它是 如何特別適合APIs的。首先,從技術(shù)上來(lái)講,REST并不是僅僅特定于APIs應(yīng)用,它更多的是一個(gè)通用的概念。然而,很明顯,我們這篇文章所討論的 REST就是在接口應(yīng)用的環(huán)境下。因此,讓我們看看一個(gè)API的基本要求已經(jīng)REST如何處理他們。
Requests 請(qǐng)求
All APIs need to accept requests. Typically, with a RESTful API, you’ll have a well-defined URL scheme. Let’s say you want to provide an API for users on your site (I know, I always use the “users” concept for my examples). Well, your URL structure would probably be something like, “api/users” and “api/users/[id]” depending on the type of operation being requested against your API. You also need to consider how you want to accept data. These days a lot of people are using JSON or XML, and I personally prefer JSON because it works well with JavaScript, and PHP has easy functionality for encoding and decoding it. If you wanted your API to be really robust, you could accept both by sniffing out the content-type of the request (i.e. application/json or application/xml), but it’s perfectly acceptable to restrict things to one content type. Heck, you could even use simple key/value pairs if you wanted.
所有的APIs都需要接收請(qǐng)求。對(duì)于一個(gè)RESTful API,你需要一個(gè)定義好的URL規(guī)則,我們假定你想要提供一個(gè)接口給你網(wǎng)站上的用戶(我知道,我總是使用"用戶"這個(gè)概念來(lái)舉例)。你的URL結(jié)構(gòu)可能 類似于這樣:"api/users"或者"api/users/[id]",這取決于請(qǐng)求接口的操作類型。同時(shí),你也需要考慮你想要怎么樣接收數(shù)據(jù)。近來(lái) 一段時(shí)間,很多人正在使用JSON或者XML,從我個(gè)人來(lái)講,我更加喜歡JSON,因?yàn)樗梢院芎玫暮蚸avascript進(jìn)行交互操作,同時(shí)PHP也可 以很簡(jiǎn)單的通過(guò)json_encode和json_decode兩個(gè)函數(shù)來(lái)對(duì)它進(jìn)行編碼和解碼。如果你希望自己的接口真正強(qiáng)健,你應(yīng)該通過(guò)識(shí)別請(qǐng)求的內(nèi)容 類型(比如application/json或者application/xml)同時(shí)允許接收兩種格式。但是,限制只接收一種類型的數(shù)據(jù)也是可以很好的 被接受。真見鬼,假如你愿意,你甚至可以使用簡(jiǎn)單的鍵/值對(duì)。
The other piece of a request is what it’s actually meant to do, such as load, save, etc. Normally, you’d have to come up with some sort of architecture that defines what action the requester (consumer) desires, but REST simplifies that. By using HTTP request methods, or verbs, we don’t need to define anything. We can just use the GET, POST, PUT, and DELETE methods, and that covers every request we’d need. You can equate the verbs to your standard crud-style stuff: GET = load/retrieve, POST = create, PUT = update, DELETE = well, delete. It’s important to note that these verbs don’t directly translate to CRUD, but it is a good way to think about them. So, going back to the above URL examples, let’s take a look at what some possible requests could mean:
??? GET request to /api/users – List all users
??? GET request to /api/users/1 – List info for user with ID of 1
??? POST request to /api/users – Create a new user
??? PUT request to /api/users/1 – Update user with ID of 1
??? DELETE request to /api/users/1 – Delete user with ID of 1
一個(gè)請(qǐng)求的其他部分是它真正要做的事情,比如加載、保存等。通常來(lái)說(shuō),你應(yīng)該提供 幾種結(jié)構(gòu)來(lái)定義請(qǐng)求者(消費(fèi)者)所希望的操作,但是REST簡(jiǎn)化了這些。通過(guò)使用HTTP請(qǐng)求方法或者動(dòng)作,我們不需要去額外定義任何東西。我們可以僅僅 使用GET,POST,PUT和DELETE方法,這些方法涵蓋了我們所需要的每一個(gè)請(qǐng)求。你可以把它和標(biāo)準(zhǔn)的增刪改查模式對(duì)應(yīng)起來(lái):GET=加載/檢索 (查,select),POST=創(chuàng)建(增,Create),PUT=更新(改,update),DELETE=刪除(DELETE)。我們要注意到,這 些動(dòng)詞并沒有直接翻譯成CRUD(增刪改查),但是這個(gè)理解它們的一個(gè)很好的方法。因此,回到剛才所舉的URL的例子,讓我們看一下一些可能的請(qǐng)求的含 義:
??? GET request to /api/users – 列舉出所有的用戶
??? GET request to /api/users/1 – 列出ID為1的用戶信息
??? POST request to /api/users – 插入一個(gè)新的用戶
??? PUT request to /api/users/1 – 更新ID為1的用戶信息
??? DELETE request to /api/users/1 – 刪除ID為1的用戶
As you hopefully see, REST has already taken care of a lot of the major headaches of creating your own API through some simple, well-understood standards and protocols, but there’s one other piece to a good API…
正如你所希望看到的,REST已經(jīng)解決了很多令人頭疼的創(chuàng)建接口的問(wèn)題,通過(guò)一些簡(jiǎn)單的,容易理解的標(biāo)準(zhǔn)和協(xié)議。但是一個(gè)好的接口還要另外一個(gè)方面...
Responses 響應(yīng)
So, REST handles requests very easily, but it also makes generating responses easy. Similar to requests, there are two main components of a RESTful response: the response body, and a status code. The response body is pretty easy to deal with. Like requests, most responses in REST are usually either JSON or XML (perhaps just plain text in the case of POSTs, but we’ll cover that later). And, like requests, the consumer can specify the response type they’d like through another part of the HTTP request spec, “Accept”. If a consumer wishes to receive an XML response, they’d just send an Accept header as a part of their request saying as much (”Accept: application/xml”). Admittedly, this method isn’t as widely adopted (tho it should be), so you have can also use the concept of an extension in the URL. For example, /api/users.xml means the consumer wants XML as a response, similarly /api/users.json means JSON (same for things like /api/users/1.json/xml). Either way you choose (I say do both), you should pick a default response type as a lot of the time people wont’ even tell you what they want. Again, I’d say go with JSON. So, no Accept header or extension (i.e. /api/users) should not fail, it should just fail-over to the default response-type.
所以,REST可以很簡(jiǎn)單的處理請(qǐng)求,同時(shí)它也可以簡(jiǎn)單的處理響應(yīng)。和請(qǐng)求類似, 一個(gè)RESTful的響應(yīng)主要包括兩個(gè)主要部分:響應(yīng)體和狀態(tài)碼。響應(yīng)體非常容易去處理。就像請(qǐng)求,大部分的REST響應(yīng)通常是JSON或者XML格式 (也許對(duì)POST操作來(lái)說(shuō)僅僅是純文本,我們稍后會(huì)討論),和請(qǐng)求類似,消費(fèi)者可以通過(guò)設(shè)置HTTP規(guī)范的"Accept"選項(xiàng)來(lái)規(guī)定自己做希望接收到的 響應(yīng)數(shù)據(jù)類型。如果一個(gè)消費(fèi)者希望接收到XML響應(yīng),他們僅僅需要發(fā)送一個(gè)包含類似于(”Accept: application/xml”)這樣的頭信息請(qǐng)求。不可否認(rèn),這種方式并沒有被廣泛的采用(即使應(yīng)該這樣),因此你也可以使用URL后綴的形式,例 如:/api/users.xml意味著消費(fèi)者希望得到XML響應(yīng),同樣,/api/users.json意味著JSON格式的響應(yīng)(/api /users/1.json/xml也是一樣)。不管你采用哪一種方法,你都需要設(shè)定一個(gè)默認(rèn)的響應(yīng)類型,因?yàn)楹芏鄷r(shí)候人們并不會(huì)告訴你他們希望什么格 式。再次地,我會(huì)選擇JSON來(lái)討論。所以,沒有Accept頭信息或者擴(kuò)展(例如:/api/users)不應(yīng)該失敗,而是采用默認(rèn)的響應(yīng)類型。
But what about errors and other important status messages associated with requests? Easy, use HTTP status codes! This is far and above one of my favorite things about creating RESTful APIs. By using HTTP status codes, you don’t need to come up with a error / success scheme for your API, it’s already done for you. For example, if a consumer POSTS to /api/users and you want to report back a successful creation, simply send a 201 status code (201 = Created). If it failed, send a 500 if it failed on your end (500 = Internal Server Error), or perhaps a 400 if they screwed up (400 = Bad request). Maybe they’re trying to POST against an API endpoint that doesn’t accept posts… send a 501 (Not implemented). Perhaps your MySQL server is down, so your API is temporarily borked… send a 503 (Service unavailable). Hopefully, you get the idea. If you’d like to read up a bit on status codes, check them out on wikipedia: List of HTTP Status Codes.
但是和請(qǐng)求有關(guān)的錯(cuò)誤和其他重要的狀態(tài)信息怎么辦呢?簡(jiǎn)單,使用HTTP的狀態(tài) 碼!這是我創(chuàng)建RESTful接口最喜歡的事情之一。通過(guò)使用HTTP狀態(tài)碼,你不需要為你的接口想出error/success規(guī)則,它已經(jīng)為你做好。 比如:假如一個(gè)消費(fèi)者提交數(shù)據(jù)(POST)到/api/users,你需要返回一個(gè)成功創(chuàng)建的消息,此時(shí)你可以簡(jiǎn)單的發(fā)送一個(gè)201狀態(tài)碼 (201=Created)。如果失敗了,服務(wù)器端失敗就發(fā)送一個(gè)500(500=內(nèi)部服務(wù)器錯(cuò)誤),如果請(qǐng)求中斷就發(fā)送一個(gè)400(400=錯(cuò)誤請(qǐng) 求)。也許他們會(huì)嘗試向一個(gè)不接受POST請(qǐng)求的接口提交數(shù)據(jù),你就可以發(fā)送一個(gè)501錯(cuò)誤(未執(zhí)行)。又或者你的MySQL服務(wù)器掛了,接口也會(huì)臨時(shí)性 的中斷,發(fā)送一個(gè)503錯(cuò)誤(服務(wù)不可用)。幸運(yùn)的是,你已經(jīng)知道了這些,假如你想要了解更多關(guān)于狀態(tài)碼的資料,可以在維基百科上查找:List of HTTP Status Codes。
I’m hoping you see all the advantages you get by leveraging the concepts of REST for your APIs. It really is super-cool, and its a shame its not more widely talked about in the PHP community (at least as far as I can tell). I think this is likely due to the lack of good documentation on how to deal with requests that aren’t GET or POST, namely PUT and DELETE. Admittedly, it is a bit goofy dealing with these, but it certainly isn’t hard. I’m also sure some of the popular frameworks out there probably have some sort of REST implementation, but I’m not a huge framework fan (for a lot of reasons that I won’t get into), and it’s also good to know these things even if somebody’s already created the solution for you.
我希望你能看到REST接口的這些優(yōu)點(diǎn)。它真的超級(jí)酷。在PHP社區(qū)社區(qū)里沒有被 廣泛的討論真是非常的遺憾(至少我知道的是這樣)。我覺得這主要是由于沒有很好的文檔介紹如何處理除了GET和POST之后的請(qǐng)求,即PUT和 DELETE。不可否認(rèn),處理這些是有點(diǎn)傻,但是卻不難。我相信一些流行的框架也許已經(jīng)有了某種REST的實(shí)現(xiàn)方式,但是我不是一個(gè)框架粉絲(原因有很 多),并且即使有人已經(jīng)為你提供了解決方案,你知道這些也是非常有好處的。
If you’re still not convinced that this is a useful API paradigm, take a look at what REST has done for Ruby on Rails. One of its major claims to fame is how easy it is to create APIs (through some sort of RoR voodoo, I’m sure), and rightly so. Granted I know very little about RoR, but the fanboys around the office have preached this point to me many times. But, I digress… let’s write some code!
如果你還是不太自信這是一個(gè)非常有用的API范式,看一下REST已經(jīng)為Ruby on Rails做了什么。其中最令人稱道的就是創(chuàng)建接口的便利性(通過(guò)某種RoR voodoo,我確信),而且確實(shí)如此。雖然我對(duì)RoR了解很少,但是辦公室的Ruby粉絲們向我說(shuō)教過(guò)很多次。不好意思跑題了,讓我們開始寫代碼。
Getting Started with REST and PHP 開始使用PHP寫REST
One last disclaimer: the code we’re about to go over is in no way intended to be used as an example of a robust solution. My main goal here is to show how to deal with the individual components of REST in PHP, and leave creating the final solution up to you.
最后一項(xiàng)免責(zé)聲明:我們接下來(lái)提供的代碼并不能被用來(lái)作為一個(gè)穩(wěn)健的解決方案。我的主要目的是向大家展示如果使用PHP處理REST的每個(gè)單獨(dú)部分,而把最后的解決方案留給你們自己去創(chuàng)建。
So, let’s dig in! I think the best way to do something practical is to create a class that will provide all the utility functions we need to create a REST API. We’ll also create a small class for storing our data. You could also then take this, extend it, and apply it to your own needs. So, let’s stub some stuff out:
那么,讓我們開始深入代碼。我認(rèn)為做一個(gè)實(shí)際事情做好的方法就是新建一個(gè) class,這個(gè)class將提供創(chuàng)建REST API所需要的所有功能性方法。現(xiàn)在我們新建一個(gè)小的class來(lái)存儲(chǔ)我們的數(shù)據(jù)。你可以把它拿去擴(kuò)展一下然后應(yīng)用到自己的需求中。我們現(xiàn)在開始寫點(diǎn)東 西:
?
?OK, so what we’ve got is a simple class for storing some information about our request (RestRequest), and a class with some static functions we can use to deal with requests and responses. As you can see, we really only have two functions to write… which is the beauty of this whole thing! Right, let’s move on…
Processing the Request
好,現(xiàn)在我們有了一個(gè)簡(jiǎn)單的class來(lái)存儲(chǔ)request的一些信息(RestRequest),和一個(gè)提供幾個(gè)靜態(tài)方法的class來(lái)處理請(qǐng)求和響應(yīng)。就像你能看到的,我們還有兩個(gè)方法要去寫,這才是整個(gè)代碼的關(guān)鍵所在,讓我們繼續(xù)...
Processing the request is pretty straight-forward, but this is where we can run into a few catches (namely with PUT and DELETE… mostly PUT). We’ll go over those in a moment, but let’s examine the RestRequest class a bit. If you’ll look at the constructor, you’ll see that we’re already interpreting the HTTP_ACCEPT header, and defaulting to JSON if none is provided. With that out of the way, we need only deal with the incoming data.
處理請(qǐng)求的過(guò)程非常直接,但是這才是我們可以有所收獲的地方(即 PUT/DELETE,大多數(shù)是PUT),我們接下來(lái)將會(huì)討論這些。但是讓我們先來(lái)檢查一下RestRequest這個(gè)class,在構(gòu)造方法中,你會(huì)看 到我們已經(jīng)處理了HTTP_ACCEPT的頭信息,并且將JSON作為默認(rèn)值。這樣,我們就只需要處理傳入的數(shù)據(jù)。
There are a few ways we could go about doing this, but let’s just assume that we’ll always get a key/value pair in our request: ‘data’ => actual data. Let’s also assume that the actual data will be JSON. As stated in my previous explanation of REST, you could look at the content-type of the request and deal with either JSON or XML, but let’s keep it simple for now. So, our process request function will end up looking something like this:
我們有幾個(gè)方法可以選擇,但是讓我們假設(shè)在請(qǐng)求信息的總是可以接收到鍵/值 對(duì):'data'=>真實(shí)數(shù)據(jù)。同時(shí)假設(shè)真實(shí)數(shù)據(jù)是JSON格式的。正如我前文所述,你可以根據(jù)請(qǐng)求的內(nèi)容類型來(lái)處理JSON或者XML,但是讓我 們現(xiàn)在簡(jiǎn)單一點(diǎn)。那么,我們處理請(qǐng)求的方法將會(huì)類似于這樣:
?Like I said, pretty straight-forward. However, a few things to note… First, you typically don’t accept data for DELETE requests, so we don’t have a case for them in the switch. Second, you’ll notice that we store both the request variables, and the parsed JSON data. This is useful as you may have other stuff as a part of your request (say an API key or something) that isn’t truly the data itself (like a new user’s name, email, etc.).
正如我剛才所說(shuō)的,非常的簡(jiǎn)單直接高效。然后,有幾點(diǎn)需要注意:首先,我們不接受 DELETE請(qǐng)求,因此我們?cè)趕witch中不提供相應(yīng)的case條件。其次,你會(huì)注意到我們把請(qǐng)求參數(shù)和解析后的JSON數(shù)據(jù)都存儲(chǔ)起來(lái)了,這在請(qǐng)求中 有其他需要處理的數(shù)據(jù)時(shí)會(huì)變得非常有用(API key或者其他),這些并不是請(qǐng)求的數(shù)據(jù)本身(比如一個(gè)新用戶的名字、電子郵箱等)。
So, how would we use this? Let’s go back to the user example. Assuming you’ve routed your request to the correct controller for users, we could have some code like this:
那么,我們?nèi)绾问褂盟?#xff1f;讓我們回到剛才user的例子。假設(shè)你已經(jīng)通過(guò)路由把請(qǐng)求對(duì)應(yīng)到正確的users控制器,代碼如下:
?Please don’t do this in a real app, this is just a quick-and-dirty example. You’d want to wrap this up in a nice control structure with everything abstracted properly, but this should help you get an idea of how to use this stuff. But I digress, let’s move on to sending a response.
Sending the Response
請(qǐng)不要在真實(shí)的應(yīng)用中這樣做,這是一個(gè)非常快速和不干凈的示例。你應(yīng)該使用一個(gè)設(shè)計(jì)良好的控制結(jié)構(gòu)來(lái)把它包裹起來(lái),適當(dāng)?shù)某橄蠡?#xff0c;但是這樣有助于你理解如何使用這些東西。讓我們繼續(xù)代碼,發(fā)送一個(gè)響應(yīng)信息。
Now that we can interpret the request, let’s move on to sending the response. We already know that all we really need to do is send the correct status code, and maybe some body (if this were a GET request, for example), but there is an important catch to responses that have no body. Say somebody made a request against our sample user API for a user that doesn’t exist (i.e. api/user/123). The appropriate status code to send is a 404 in this case, but simply sending the status code in the headers isn’t enough. If you viewed that page in your web browser, you would get a blank screen. This is because Apache (or whatever your web server runs on) isn’t sending the status code, so there’s no status page. We’ll need to take this into account when we build out our function. Keeping all that in mind, here’s what the code should look like:
既然我們已經(jīng)可以解析請(qǐng)求,那么接下來(lái)我們繼續(xù)來(lái)發(fā)送一個(gè)響應(yīng)。我們已經(jīng)知道我們 真正需要去做的是發(fā)送一個(gè)正確的狀態(tài)碼和一些響應(yīng)消息體(例如這是一個(gè)GET請(qǐng)求),但是對(duì)于沒有消息體的響應(yīng)來(lái)說(shuō)有一個(gè)重要的catch(譯者:不好意 思,實(shí)在是不知道如何翻譯這個(gè)詞)。假定某個(gè)人向我們的user接口發(fā)送一個(gè)請(qǐng)求某個(gè)用戶信息的請(qǐng)求,而這個(gè)用戶卻不存在(比如:api/user /123),此時(shí)系統(tǒng)發(fā)送最合適的狀態(tài)碼是404。但是簡(jiǎn)單的在頭信息中發(fā)送狀態(tài)碼是不夠的,如果你通過(guò)網(wǎng)頁(yè)瀏覽器瀏覽該頁(yè)面,你會(huì)看到一個(gè)空白頁(yè)面。這 是因?yàn)閍pache服務(wù)器(或者其他服務(wù)器)并不會(huì)發(fā)送此狀態(tài)碼,因此沒有狀態(tài)頁(yè)面。我們需要在構(gòu)建方法的時(shí)候考慮到這一點(diǎn)。把所有的東西都考慮進(jìn)去,代 碼會(huì)類似于下面這樣:
?That’s It! We technically have everything we need now to process requests and send responses. Let’s talk a bit more about why we need to have a standard body response or a custom one. For GET requests, this is pretty obvious, we need to send XML / JSON content instead of a status page (provided the request was valid). However, there’s also POSTs to deal with. Inside of your apps, when you create a new entity, you probably fetch the new entity’s ID via something like mysql_insert_id(). Well, if a user posts to your API, they’ll probably want that new ID as well. What I’ll usually do in this case is simply send the new ID as the body (with a 201 status code), but you could also wrap that in XML or JSON if you’d like.
就這樣,從技術(shù)上來(lái)說(shuō),我們已經(jīng)具備了處理請(qǐng)求和發(fā)送響應(yīng)的所有東西。下面我們?cè)?討論以下為什么我們需要一個(gè)標(biāo)準(zhǔn)的相應(yīng)提或者一個(gè)自定義的。對(duì)于GET請(qǐng)求來(lái)說(shuō),非常明顯,我們需要發(fā)送XML/JSON內(nèi)容而不是一個(gè)狀態(tài)頁(yè)(假設(shè)請(qǐng)求 是合法的)。然后,我們還有POST請(qǐng)求要去處理。在你的應(yīng)用內(nèi)部,當(dāng)你創(chuàng)建一個(gè)新的實(shí)體,你也許需要使用通過(guò)類似于mysql_insert_id() 這樣的函數(shù)得到這個(gè)實(shí)體的ID。那么,當(dāng)一個(gè)用戶提交到你的接口,他們將很可能想要知道這個(gè)新的ID是什么。在這種情況下,我通常的做法是非常簡(jiǎn)單的把這 個(gè)新ID作為響應(yīng)的消息體發(fā)送給用戶(同時(shí)發(fā)送一個(gè)201的狀態(tài)碼頭信息),但是如果你愿意,你也可以使用XML或者JSON來(lái)把它包裹起來(lái)。
So, let’s extend our sample implementation a bit:
現(xiàn)在,讓我們來(lái)擴(kuò)展一下我們的例子,讓它更加實(shí)際一點(diǎn):
?Again, this is just an example, but it does show off (I think, at least) how little effort it takes to implement RESTful stuff.
Wrapping Up
再一次說(shuō)明,這是一個(gè)例子,但它確實(shí)向我們展示了(至少我認(rèn)為是)它能輕而易舉的實(shí)現(xiàn)RESTful接口。
So, that’s about it. I’m pretty confident that I’ve beaten the point that this should be quite easy into the ground, so I’d like to close with how you can take this stuff further and perhaps properly implement it.
所以,這就是它。我非常的自信的說(shuō),我已經(jīng)把這些解釋的非常清楚。因此,我就不再贅述你如何具體實(shí)現(xiàn)它。
In a real-world MVC application, what you would probably want to do is set up a controller for your API that loads individual API controllers. For example, using the above stuff, we’d possibly create a UserRestController which had four methods: get(), put(), post(), and delete(). The API controller would look at the request and determine which method to invoke on that controller. That method would then use the utils to process the request, do what it needs to do data-wise, then use the utils to send a response.
在一個(gè)真實(shí)的MVC應(yīng)用中,也許你想要做的就是為你的每個(gè)接口創(chuàng)建一個(gè)單獨(dú)的控制 器。例如,利用上面的東西,我們可以創(chuàng)建一個(gè)UserRestController控制器,這個(gè)控制器有四個(gè)方法,分別為:get(), put(), post(), 和 delete()。接口控制器將會(huì)查看請(qǐng)求類型然后決定哪個(gè)方法會(huì)被執(zhí)行。這個(gè)方法會(huì)再使用工具來(lái)處理請(qǐng)求,處理數(shù)據(jù),然后使用工具發(fā)送響應(yīng)。
You could also take it a step further than that, and abstract out your API controller and data models a bit more. Rather than explicitly creating a controller for every data model in your app, you could add some logic into your API controller to first look for an explicitly defined controller, and if none is found, try to look for an existing model. For example, the url “api/user/1″, would first trigger a lookup for a “user” rest controller. If none is found, it could then look for a model called “user” in your app. If one is found, you could write up a bit of automated voodoo to automatically process all the requests against those models.
你也許會(huì)比現(xiàn)在更進(jìn)一步,把你的接口控制器和數(shù)據(jù)模型抽象出來(lái),而不是明確的為每 一個(gè)數(shù)據(jù)模型創(chuàng)建控制器,你可以給你的接口控制器添加一些邏輯,先去查找一個(gè)明確定義好的控制器,如果沒有,試著去查找一個(gè)已經(jīng)存在的模型。例如:網(wǎng) 址"api/user/1"將會(huì)首先觸發(fā)查找一個(gè)叫user的最終控制器,如果沒有,它會(huì)查找應(yīng)用中叫user的模型,如果找到了,你可以寫一個(gè)自動(dòng)化的 方法來(lái)自動(dòng)處理所有請(qǐng)求這個(gè)模型的請(qǐng)求。
Going even further, you could then make a generic “l(fā)ist-all” method that works similar to the previous paragraph’s example. Say your url was “api/users”. The API controller could first check for a “users” rest controller, and if none was found, recognize that users is pluaralized, depluralize it, and then look for a “user” model. If one’s found, load a list the list of users and send that off.
再進(jìn)一步,你可以建立一個(gè)通用的"list-all"方法,就像上面一段中的例子 一樣。假定你的url是"api/usrs",接口控制器首先會(huì)查找叫users的控制器,如果沒有找到,確認(rèn)users是復(fù)數(shù),把它變成單數(shù),然后查找 一個(gè)叫user的模型,如果找到了,加載一個(gè)用戶列表然后把他們發(fā)送出去。
Finally, you could add digest authentication to your API quite easily as well. Say you only wanted properly authenticated users to access your API, well, you could throw some code like this into your process request functionality (borrowed from an existing app of mine, so there’s some constants and variables referenced that aren’t defined in this snippet):
最后,你可以給你的接口添加簡(jiǎn)單的身份驗(yàn)證。假定你僅僅希望適當(dāng)?shù)尿?yàn)證訪問(wèn)你的接口的用戶,那么,你可以在處理請(qǐng)求的方法中添加類似于下面的一些代碼(借用我的一個(gè)現(xiàn)有應(yīng)用,因此有一些常量和變量在這個(gè)代碼片段里面并沒有被定義):
?Pretty cool stuff, huh? With a little bit of code and some clever logic, you can add a fully functional REST API to your apps very quickly. I’m not just saying that to cheerlead the concept either, I implemented this stuff into one of my personal frameworks in about half a day, and then spent another half day adding all sorts of cool magic to it. If you (the reader) are interested in seeing my final implementation, drop me a note in the comments and I’d be happy to share it with you! Also, if you’ve got any cool ideas you’d like to share, be sure to drop those in the comments as well… if I like it enough, I’d even let you guest author your own article on the subject!
非常酷,對(duì)吧?通過(guò)少量的代碼和一些智能的邏輯,你可以非常快速的給你的應(yīng)用添加 全功能的REST接口。我并不僅僅是支持這個(gè)概念,我已經(jīng)在我個(gè)人的框架里面實(shí)現(xiàn)了這些東西,而這些僅僅花費(fèi)了半天的時(shí)間,然后再花費(fèi)半天時(shí)間添加一些非 常酷的東西。如果你(讀者)對(duì)我最終的實(shí)現(xiàn)感興趣,請(qǐng)?jiān)谠u(píng)論中留言,我會(huì)非常樂(lè)趣和你分享它。同時(shí),如果你有什么比較酷的想法,也歡迎通過(guò)評(píng)論和我進(jìn)行分 享。如果我足夠喜歡它,我會(huì)邀請(qǐng)你在這里發(fā)表自己的文章。
?
轉(zhuǎn)載于:https://www.cnblogs.com/kudosharry/articles/2550366.html
總結(jié)
以上是生活随笔為你收集整理的使用PHP创建一个REST API(Create a REST API with PHP)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 废铝多少钱啊?
- 下一篇: php连接mssql数据库的几种方式