Czym dokładnie jest programowanie RESTful?

Czym dokładnie jest programowanie RESTful?

REST jest podstawową zasadą architektury sieci. Niesamowitą rzeczą w sieci jest fakt, że klienci (przeglądarki) i serwery mogą wchodzić w złożone interakcje bez wcześniejszej wiedzy klienta o serwerze i zasobach, które on przechowuje. Kluczowym ograniczeniem jest to, że serwer i klient muszą się zgodzić co do użytych mediów, którymi w przypadku sieci jest HTML.

API, które stosuje się do zasad REST nie wymaga od klienta wiedzy o strukturze API. Serwer musi raczej dostarczyć klientowi wszelkich informacji potrzebnych do interakcji z usługą. Przykładem może być formularz HTML: Serwer określa lokalizację zasobu i wymagane pola. Przeglądarka nie wie z góry, gdzie ma przesłać informacje i nie wie z góry, jakie informacje ma przesłać. Obie formy informacji są w całości dostarczane przez serwer. (Ta zasada jest nazywana HATEOAS: Hypermedia As The Engine Of Application State.)

Jak to się ma do HTTP i jak można to zastosować w praktyce? HTTP jest zorientowany na czasowniki i zasoby. Dwa czasowniki w powszechnym użyciu to GET i POST, które myślę, że każdy rozpozna. Jednakże standard HTTP definiuje kilka innych, takich jak PUT i DELETE. Czasowniki te są następnie stosowane do zasobów, zgodnie z instrukcjami dostarczonymi przez serwer.

Na przykład, wyobraźmy sobie, że mamy bazę danych użytkowników, która jest zarządzana przez usługę sieciową. Nasza usługa używa niestandardowego hipermedium opartego na JSON, dla którego przypisujemy mimetype application/json+userdb (może być również application/xml+userdb oraz application/whatever+userdb - wiele typów mediów może być obsługiwanych). Klient i serwer zostały zaprogramowane tak, aby rozumieć ten format, ale nie wiedzą nic o sobie nawzajem. Jak zauważa Roy Fielding:

A REST API powinien spędzić prawie cały swój wysiłek opisowy w. definiując typ(y) mediów używanych do reprezentowania zasobów i napędzania stanu aplikacji, lub w definiowaniu rozszerzonych nazw relacji i/lub hipertekstowych znaczników dla istniejących standardowych typów mediów.

Żądanie dla podstawowego zasobu / może zwrócić coś takiego:

Request.

GET /
Accept: application/json+userdb

Response

200 OK
Content-Type: application/json+userdb

{
    "version": "1.0",
    "links": [
        {
            "href": "/user",
            "rel": "list",
            "method": "GET"
        },
        {
            "href": "/user",
            "rel": "create",
            "method": "POST"
        }
    ]
}

Z opisu naszych mediów wiemy, że informacje o powiązanych zasobach możemy znaleźć w sekcjach zwanych "linkami". Nazywa się to Hypermedia controls. W tym przypadku, z takiej sekcji możemy dowiedzieć się, że możemy znaleźć listę użytkowników, wykonując kolejne żądanie dla /user:

Request.

GET /user
Accept: application/json+userdb

Response

200 OK
Content-Type: application/json+userdb

{
    "users": [
        {
            "id": 1,
            "name": "Emil",
            "country: "Sweden",
            "links": [
                {
                    "href": "/user/1",
                    "rel": "self",
                    "method": "GET"
                },
                {
                    "href": "/user/1",
                    "rel": "edit",
                    "method": "PUT"
                },
                {
                    "href": "/user/1",
                    "rel": "delete",
                    "method": "DELETE"
                }
            ]
        },
        {
            "id": 2,
            "name": "Adam",
            "country: "Scotland",
            "links": [
                {
                    "href": "/user/2",
                    "rel": "self",
                    "method": "GET"
                },
                {
                    "href": "/user/2",
                    "rel": "edit",
                    "method": "PUT"
                },
                {
                    "href": "/user/2",
                    "rel": "delete",
                    "method": "DELETE"
                }
            ]
        }
    ],
    "links": [
        {
            "href": "/user",
            "rel": "create",
            "method": "POST"
        }
    ]
}

Możemy wiele powiedzieć z tej odpowiedzi. Na przykład, teraz wiemy, że możemy stworzyć nowego użytkownika przez POST do /user:

Request

POST /user
Accept: application/json+userdb
Content-Type: application/json+userdb

{
    "name": "Karl",
    "country": "Austria"
}

Response

201 Created
Content-Type: application/json+userdb

{
    "user": {
        "id": 3,
        "name": "Karl",
        "country": "Austria",
        "links": [
            {
                "href": "/user/3",
                "rel": "self",
                "method": "GET"
            },
            {
                "href": "/user/3",
                "rel": "edit",
                "method": "PUT"
            },
            {
                "href": "/user/3",
                "rel": "delete",
                "method": "DELETE"
            }
        ]
    },
    "links": {
       "href": "/user",
       "rel": "list",
       "method": "GET"
    }
}

Wiemy też, że możemy zmieniać istniejące dane:

Request

PUT /user/1
Accept: application/json+userdb
Content-Type: application/json+userdb

{
    "name": "Emil",
    "country": "Bhutan"
}

Response

200 OK
Content-Type: application/json+userdb

{
    "user": {
        "id": 1,
        "name": "Emil",
        "country": "Bhutan",
        "links": [
            {
                "href": "/user/1",
                "rel": "self",
                "method": "GET"
            },
            {
                "href": "/user/1",
                "rel": "edit",
                "method": "PUT"
            },
            {
                "href": "/user/1",
                "rel": "delete",
                "method": "DELETE"
            }
        ]
    },
    "links": {
       "href": "/user",
       "rel": "list",
       "method": "GET"
    }
}

Zauważ, że używamy różnych czasowników HTTP (GET, PUT, POST, DELETE itd.) do manipulowania tymi zasobami, i że jedyną wiedzą, którą zakładamy po stronie klienta jest nasza definicja mediów.

Dalsze czytanie:

(Ta odpowiedź była przedmiotem dość dużej krytyki za brak punktu. W przeważającej części była to uczciwa krytyka. To, co pierwotnie opisałem, było bardziej zgodne z tym, jak REST był zwykle wdrażany kilka lat temu, kiedy po raz pierwszy napisałem to, a nie jego prawdziwe znaczenie. I've zrewidował odpowiedź, aby lepiej reprezentować prawdziwe znaczenie).

Komentarze (39)

REST to wykorzystanie różnych metod HTTP (głównie GET/PUT/DELETE) do manipulowania danymi.

Zamiast używać konkretnego adresu URL do usunięcia metody (powiedzmy, /user/123/delete), wysyłasz żądanie DELETE do adresu URL /user/[id], aby edytować użytkownika, aby pobrać informacje o użytkowniku wysyłasz żądanie GET do /user/[id].

Na przykład, zamiast zestawu adresów URL, które mogą wyglądać jak niektóre z poniższych...

GET /delete_user.x?id=123
GET /user/delete
GET /new_user.x
GET /user/new
GET /user?id=1
GET /user/id/1

Używasz "czasowników" HTTP i masz...

GET /user/2
DELETE /user/2
PUT /user
Komentarze (5)

Jest to programowanie, w którym architektura twojego systemu pasuje do stylu REST przedstawionego przez Roya Fieldinga w jego pracy dyplomowej. Ponieważ jest to styl architektoniczny, który opisuje sieć (mniej więcej), wiele osób jest nim zainteresowanych.

Bonusowa odpowiedź: Nie. O ile nie studiujesz architektury oprogramowania jako pracownik akademicki lub nie projektujesz usług internetowych, nie ma powodu, abyś słyszał ten termin.

Komentarze (4)