Τι ακριβώς είναι ο προγραμματισμός RESTful;

Τι ακριβώς είναι ο προγραμματισμός RESTful;

Το REST είναι η βασική αρχιτεκτονική αρχή του διαδικτύου. Το εκπληκτικό με τον ιστό είναι το γεγονός ότι οι πελάτες (φυλλομετρητές) και οι διακομιστές μπορούν να αλληλεπιδρούν με πολύπλοκους τρόπους χωρίς ο πελάτης να γνωρίζει εκ των προτέρων τίποτα για τον διακομιστή και τους πόρους που φιλοξενεί. Ο βασικός περιορισμός είναι ότι ο διακομιστής και ο πελάτης πρέπει να συμφωνούν για τα μέσα που χρησιμοποιούνται, τα οποία στην περίπτωση του ιστού είναι η HTML.

Ένα API που ακολουθεί τις αρχές του REST δεν απαιτεί από τον πελάτη να γνωρίζει τίποτα για τη δομή του API. Αντίθετα, ο διακομιστής πρέπει να παρέχει οποιαδήποτε πληροφορία χρειάζεται ο πελάτης για να αλληλεπιδράσει με την υπηρεσία. Μια φόρμα HTML είναι ένα παράδειγμα αυτού του είδους: Ο διακομιστής καθορίζει τη θέση του πόρου και τα απαιτούμενα πεδία. Το πρόγραμμα περιήγησης δεν γνωρίζει εκ των προτέρων πού να υποβάλει τις πληροφορίες και δεν γνωρίζει εκ των προτέρων ποιες πληροφορίες να υποβάλει. Και οι δύο μορφές πληροφοριών παρέχονται εξ ολοκλήρου από το διακομιστή. (Αυτή η αρχή ονομάζεται HATEOAS: Hypermedia As The Engine Of Application State.)

Πώς εφαρμόζεται λοιπόν αυτό στο HTTP και πώς μπορεί να εφαρμοστεί στην πράξη; Το HTTP είναι προσανατολισμένο γύρω από ρήματα και πόρους. Τα δύο ρήματα στην επικρατούσα χρήση είναι τα GET και POST, τα οποία νομίζω ότι όλοι θα αναγνωρίσουν. Ωστόσο, το πρότυπο HTTP ορίζει πολλά άλλα, όπως τα ρήματα PUT και DELETE. Αυτά τα ρήματα εφαρμόζονται στη συνέχεια στους πόρους, σύμφωνα με τις οδηγίες που παρέχονται από τον διακομιστή.

Για παράδειγμα, ας φανταστούμε ότι έχουμε μια βάση δεδομένων χρηστών, την οποία διαχειρίζεται μια υπηρεσία ιστού. Η υπηρεσία μας χρησιμοποιεί ένα προσαρμοσμένο υπερμέσο βασισμένο στο JSON, για το οποίο αναθέτουμε το mimetype application/json+userdb (μπορεί επίσης να υπάρχει ένα application/xml+userdb και application/whatever+userdb - πολλοί τύποι μέσων μπορεί να υποστηρίζονται). Ο πελάτης και ο διακομιστής έχουν προγραμματιστεί να κατανοούν αυτή τη μορφή, αλλά δεν γνωρίζουν τίποτα ο ένας για τον άλλον. Όπως επισημαίνει ο [Roy Fielding][1]:

Ένα REST API θα πρέπει να ξοδεύει σχεδόν όλη την προσπάθεια περιγραφής του σε τον ορισμό του τύπου πολυμέσων που χρησιμοποιούνται για την αναπαράσταση πόρων και την οδήγηση κατάσταση της εφαρμογής, ή στον ορισμό εκτεταμένων ονομάτων σχέσεων ή/και σήμανση με δυνατότητα υπερκειμένου για τους υπάρχοντες τυποποιημένους τύπους μέσων.

Μια αίτηση για τον βασικό πόρο / μπορεί να επιστρέψει κάτι τέτοιο:

Αίτημα

GET /
Accept: application/json+userdb

Απάντηση

200 OK
Content-Type: application/json+userdb

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

Γνωρίζουμε από την περιγραφή του μέσου μας ότι μπορούμε να βρούμε πληροφορίες σχετικά με συναφείς πόρους από τις ενότητες που ονομάζονται "σύνδεσμοι". Αυτό ονομάζεται Ελέγχοι υπερμέσων. Σε αυτή την περίπτωση, μπορούμε να πούμε από ένα τέτοιο τμήμα ότι μπορούμε να βρούμε μια λίστα χρηστών κάνοντας μια άλλη αίτηση για το /user:

Αίτημα

GET /user
Accept: application/json+userdb

Απάντηση

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

Μπορούμε να πούμε πολλά από αυτή την απάντηση. Για παράδειγμα, τώρα ξέρουμε ότι μπορούμε να δημιουργήσουμε έναν νέο χρήστη με POST στο /user:

Request

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

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

Απάντηση

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

Γνωρίζουμε επίσης ότι μπορούμε να αλλάξουμε τα υπάρχοντα δεδομένα:

Αίτημα

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

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

Απάντηση

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

Παρατηρήστε ότι χρησιμοποιούμε διαφορετικά ρήματα HTTP (GET, PUT, POST, DELETE κ.λπ.) για να χειριστούμε αυτούς τους πόρους και ότι η μόνη γνώση που προϋποθέτουμε από την πλευρά του πελάτη είναι ο ορισμός των μέσων μας.

Περαιτέρω ανάγνωση:

Σχόλια (39)

Το REST χρησιμοποιεί τις διάφορες μεθόδους HTTP (κυρίως GET/PUT/DELETE) για τον χειρισμό δεδομένων.

Αντί να χρησιμοποιείτε μια συγκεκριμένη διεύθυνση URL για να διαγράψετε μια μέθοδο (π.χ. /user/123/delete), θα στέλνατε μια αίτηση DELETE στη διεύθυνση URL /user/[id], για να επεξεργαστείτε έναν χρήστη, για να ανακτήσετε πληροφορίες για έναν χρήστη στέλνετε μια αίτηση GET στη διεύθυνση /user/[id].

Για παράδειγμα, αντί για ένα σύνολο διευθύνσεων URL που μπορεί να μοιάζουν με κάποια από τα παρακάτω...

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

Χρησιμοποιείτε τα ρήματα HTTP "verbs" και έχετε..

GET /user/2
DELETE /user/2
PUT /user
Σχόλια (5)

Πρόκειται για προγραμματισμό όπου η αρχιτεκτονική του συστήματός σας ταιριάζει με το στυλ REST που καθορίζει ο Roy Fielding στη διατριβή του. Δεδομένου ότι αυτό είναι το αρχιτεκτονικό στυλ που περιγράφει τον ιστό (λίγο πολύ), πολλοί άνθρωποι ενδιαφέρονται γι' αυτό.

Απάντηση μπόνους: Δεν υπάρχει πραγματικά κανένας λόγος να έχετε ακούσει τον όρο.

Σχόλια (4)