Kaj točno je programiranje RESTful?

Kaj točno je programiranje RESTful?

REST je temeljno arhitekturno načelo spleta. Odjemalci (brskalniki) in strežniki lahko med seboj komunicirajo na zapletene načine, ne da bi odjemalec vnaprej vedel kar koli o strežniku in virih, ki jih ta gosti. Ključna omejitev je, da se morata strežnik in odjemalec strinjati glede uporabljenega medija, ki je v primeru spleta HTML.

API, ki upošteva načela REST, odjemalcu ne zahteva, da bi kar koli vedel o strukturi API. Namesto tega mora strežnik zagotoviti vse informacije, ki jih odjemalec potrebuje za interakcijo s storitvijo. Primer tega je obrazec HTML: Strežnik določi lokacijo vira in zahtevana polja. Brskalnik ne ve vnaprej, kam naj pošlje informacije, in ne ve vnaprej, katere informacije naj pošlje. Obe obliki informacij v celoti zagotovi strežnik. (To načelo se imenuje HATEOAS: Hypermedia As The Engine Of Application State.)

Tako, kako to velja za HTTP in kako se lahko izvaja v praksi? HTTP je usmerjen v glagole in vire. Dva glagola v splošni rabi sta GET in POST, ki ju po mojem mnenju vsi prepoznajo. Vendar standard HTTP opredeljuje še več drugih, kot sta PUT in DELETE. Ti glagoli se nato uporabljajo za vire v skladu z navodili strežnika.

Predstavljajmo si na primer, da imamo podatkovno zbirko uporabnikov, ki jo upravlja spletna storitev. Naša storitev uporablja lasten hipermedij, ki temelji na JSON-u, za katerega dodelimo mimetype application/json+userdb (lahko tudi application/xml+userdb in application/whatever+userdb - podprtih je lahko veliko vrst medijev). Odjemalec in strežnik sta programirana tako, da razumeta ta format, vendar drug o drugem ne vesta ničesar. Kot poudarja Roy Fielding:

API REST bi moral skoraj ves svoj opisni napor porabiti za opredelitev medijskih tipov, ki se uporabljajo za predstavitev virov in vodenje stanje aplikacije, ali pri opredeljevanju razširjenih imen relacij in/ali označevanja s hipertekstom za obstoječe standardne vrste medijev.

Zahteva za osnovni vir / lahko vrne nekaj takega:

Zahtevek: Zahtevek

GET /
Accept: application/json+userdb

Odgovor

200 OK
Content-Type: application/json+userdb

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

Iz opisa našega medija vemo, da lahko informacije o sorodnih virih najdemo v razdelkih, imenovanih "povezave". Temu pravimo Hypermedia controls (nadzor nad hipermediji). V tem primeru lahko iz takšnega razdelka razberemo, da lahko najdemo seznam uporabnikov tako, da naredimo še eno zahtevo za /user:

zahtevek

GET /user
Accept: application/json+userdb

Odgovor

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"
        }
    ]
}

Iz tega odgovora lahko veliko razberemo. Zdaj na primer vemo, da lahko ustvarimo novega uporabnika tako, da POST pošljemo na /user:

zahtevek

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

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

Odgovor

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

Vemo tudi, da lahko spremenimo obstoječe podatke:

Zahteva

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

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

Odgovor

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

Opazite, da uporabljamo različne glagole HTTP (GET, PUT, POST, DELETE itd.) za manipulacijo s temi viri in da je edino znanje, ki ga predpostavljamo na strani odjemalca, naša opredelitev medija.

Nadaljnje branje:

(Ta odgovor je bil deležen precej kritik, ker je zgrešil bistvo. Večinoma je bila to poštena kritika. To, kar sem prvotno opisal, je bilo bolj v skladu s tem, kako se je REST običajno izvajal pred nekaj leti, ko sem to prvič napisal, kot pa z njegovim pravim pomenom. Odgovor sem popravil, da bi bolje predstavil pravi pomen.)

Komentarji (39)

REST uporablja različne metode HTTP (predvsem GET/PUT/DELETE) za manipulacijo s podatki.

Namesto da bi za brisanje metode uporabili določen URL (na primer /user/123/delete), bi poslali zahtevo DELETE na URL /user/[id], za urejanje uporabnika, za pridobivanje informacij o uporabniku pa bi poslali zahtevo GET na /user/[id].

Namesto tega lahko na primer uporabite niz naslovov URL, ki so lahko videti kot nekateri od naslednjih.

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

Uporabljate glagole HTTP "in imate..

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

To je programiranje, pri katerem arhitektura vašega sistema ustreza slogu REST, ki ga je v svoji diplomski nalogi določil Roy Fielding. Ker je to arhitekturni slog, ki (bolj ali manj) opisuje splet, se zanj zanima veliko ljudi.

Bonusni odgovor: Če ne študirate arhitekture programske opreme na fakulteti ali oblikujete spletnih storitev, ni razloga, da bi slišali ta izraz.

Komentarji (4)