10 καλύτερες πρακτικές για τη σύνταξη API REST Node.js

Σε αυτό το άρθρο, καλύπτουμε τις βέλτιστες πρακτικές για τη σύνταξη API REST Node.js, συμπεριλαμβανομένων θεμάτων όπως ονομάζοντας τις διαδρομές σας, τον έλεγχο ταυτότητας, τη δοκιμή μαύρου κουτιού και τη χρήση κατάλληλων κεφαλίδων προσωρινής μνήμης για αυτούς τους πόρους.

Μία από τις πιο δημοφιλείς περιπτώσεις χρήσης για το Node.js είναι να γράψει τα RESTful API που το χρησιμοποιούν. Παρόλα αυτά, ενώ βοηθάμε τους πελάτες μας να βρουν προβλήματα στις εφαρμογές τους με το Trace, το εργαλείο παρακολούθησης Node.js, βιώνουμε συνεχώς ότι οι προγραμματιστές έχουν πολλά προβλήματα με τα API REST.

Ελπίζω ότι αυτές οι βέλτιστες πρακτικές που χρησιμοποιούμε στο RisingStack μπορούν να βοηθήσουν:

# 1: Χρησιμοποιήστε μεθόδους HTTP και διαδρομές API

Φανταστείτε ότι χτίζετε ένα RESTful API του Node.js για τη δημιουργία, την ενημέρωση, την ανάκτηση ή τη διαγραφή χρηστών. Για αυτές τις λειτουργίες το HTTP έχει ήδη το κατάλληλο σύνολο εργαλείων: POST, PUT, GET, PATCH ή DELETE.

Ως βέλτιστη πρακτική, οι διαδρομές API θα πρέπει πάντα να χρησιμοποιούν τα ουσιαστικά ως αναγνωριστικά πόρων. Μιλώντας για τους πόρους του χρήστη, η δρομολόγηση μπορεί να φαίνεται ως εξής:

  • POST / χρήστη ή PUT / χρήστη: / id για να δημιουργήσετε ένα νέο χρήστη,
  • GET / χρήστη για την ανάκτηση μιας λίστας χρηστών,
  • GET / user /: id για την ανάκτηση ενός χρήστη,
  • PATCH / user /: id για να τροποποιήσετε μια υπάρχουσα εγγραφή χρήστη,
  • DELETE / user /: id για να καταργήσετε έναν χρήστη.

# 2: Χρησιμοποιήστε τους κωδικούς κατάστασης HTTP σωστά

Αν κάτι δεν πάει καλά κατά την εκτέλεση μιας αίτησης, πρέπει να ορίσετε τον σωστό κωδικό κατάστασης για εκείνον στην απάντηση:

  • 2xx, αν όλα ήταν εντάξει,
  • 3xx, εάν μετακινήθηκε ο πόρος,
  • 4xx, εάν το αίτημα δεν μπορεί να ικανοποιηθεί εξαιτίας σφάλματος πελάτη (όπως ζητώντας έναν πόρο που δεν υπάρχει),
  • 5xx, εάν κάτι πήγε στραβά στην πλευρά του API (όπως συνέβη σε μια εξαίρεση).

Εάν χρησιμοποιείτε το Express, ο καθορισμός του κωδικού κατάστασης είναι τόσο εύκολος όσο ο res.status (500) .send ({error: 'Παρουσιάστηκε σφάλμα εσωτερικού διακομιστή'}). Ομοίως με το Restify: res.status (201).

Για μια πλήρη λίστα, ελέγξτε τη λίστα των κωδικών κατάστασης HTTP

# 3: Χρησιμοποιήστε τις κεφαλίδες HTTP για την αποστολή μεταδεδομένων

Για να επισυνάψετε μεταδεδομένα σχετικά με το ωφέλιμο φορτίο που πρόκειται να στείλετε, χρησιμοποιήστε κεφαλίδες HTTP. Κεφαλίδες όπως αυτό μπορεί να είναι πληροφορίες σχετικά με:

  • σελιδοποίηση,
  • ρυθμό περιορισμού,
  • ή τον έλεγχο ταυτότητας.

Μπορείτε να βρείτε μια λίστα τυποποιημένων κεφαλίδων HTTP εδώ.

Εάν πρέπει να ορίσετε προσαρμοσμένα μεταδεδομένα στις κεφαλίδες σας, ήταν μια καλή πρακτική να τους δώσετε προθέματα με το Χ. Για παράδειγμα, αν χρησιμοποιούσατε μάρκες CSRF, ήταν ένας κοινός (αλλά μη τυποποιημένος) τρόπος να τους ονομάσετε X-Csrf -Ενδειξη. Ωστόσο, με το RFC 6648 απολύθηκαν. Τα νέα API πρέπει να καταβάλλουν κάθε δυνατή προσπάθεια ώστε να μην χρησιμοποιούν ονόματα κεφαλίδων που μπορούν να έρθουν σε σύγκρουση με άλλες εφαρμογές. Για παράδειγμα, το OpenStack προθέτει τις κεφαλίδες του με το OpenStack:

OpenStack-ταυτότητα-ταυτότητα λογαριασμού
OpenStack-Networking-Host-Name
Πολιτική αποθήκευσης OpenStack-Object-Storage

Σημειώστε ότι το πρότυπο HTTP δεν ορίζει κανένα όριο μεγέθους στις κεφαλίδες. Ωστόσο, το Node.js (από την εγγραφή αυτού του άρθρου) επιβάλλει ένα όριο μεγέθους 80KB στο αντικείμενο κεφαλίδων για πρακτικούς λόγους.

Msgstr "" "Μην επιτρέπετε να υπερβεί το HTTP_MAX_HEADER_SIZE το συνολικό μέγεθος των κεφαλίδων HTTP (συμπεριλαμβανομένης της γραμμής κατάστασης). Αυτός ο έλεγχος είναι εδώ για να προστατεύσει τους ενσωματωτές από επιθέσεις άρνησης εξυπηρέτησης όπου ο επιτιθέμενος μας τροφοδοτεί μια ατελείωτη κεφαλίδα που ο ενσωματωτής διατηρεί προσωρινή αποθήκευση ».
Από τον αναλυτή HTTP Node.js

# 4: Επιλέξτε το κατάλληλο πλαίσιο για το API REST του Node.js

Είναι σημαντικό να επιλέξετε το πλαίσιο που ταιριάζει περισσότερο στη χρήση σας.

Express, Koa ή Hapi

Τα Express, Koa και Hapi μπορούν να χρησιμοποιηθούν για τη δημιουργία εφαρμογών του προγράμματος περιήγησης, και ως εκ τούτου, υποστηρίζουν τη δημιουργία και την απόδοση - για να αναφέρουμε μερικά μόνο χαρακτηριστικά. Αν η αίτησή σας πρέπει να παρέχει και την πλευρά που βλέπει ο χρήστης, είναι λογικό να πάτε για αυτούς.

Επιβεβαιώστε

Από την άλλη πλευρά, το Restify επικεντρώνεται στην παροχή βοήθειας για την κατασκευή υπηρεσιών REST. Υπάρχει για να σας επιτρέψει να δημιουργήσετε "αυστηρές" υπηρεσίες API που να είναι διατηρήσιμες και παρατηρήσιμες. Το Restify έρχεται επίσης με αυτόματη υποστήριξη DTrace για όλους τους χειριστές σας.

Το Restify χρησιμοποιείται στην παραγωγή σε σημαντικές εφαρμογές όπως npm ή Netflix.

# 5: Black-Box Δοκιμάστε τα API REST του Node.js

Ένας από τους καλύτερους τρόπους για να δοκιμάσετε τα API REST σας είναι να τα αντιμετωπίζετε ως μαύρα κουτιά.

Η δοκιμή Black-Box είναι μια μέθοδος ελέγχου όπου εξετάζεται η λειτουργικότητα μιας εφαρμογής χωρίς να γνωρίζει τις εσωτερικές της δομές ή λειτουργίες. Επομένως, καμία από τις εξαρτήσεις δεν είναι κοροϊδευμένη ή σπασμένη, αλλά το σύστημα δοκιμάζεται στο σύνολό του.

Μία από τις ενότητες που μπορούν να σας βοηθήσουν με την δοκιμή μαύρου κουτιού Node.js REST APIs είναι supertest.

Μια απλή δοκιμαστική περίπτωση που ελέγχει αν ένας χρήστης επιστρέφεται χρησιμοποιώντας τον δοκιμαστή mocha μπορεί να εφαρμοστεί ως εξής:

const request = require ('supertest')
 
περιγράψτε ('GET / χρήστη /: id', λειτουργία () {
  αυτό ('επιστρέφει χρήστη', λειτουργία () {
    // Οι νεότερες εκδόσεις mocha δέχονται και υποσχέσεις
    αίτημα επιστροφής (app)
      .get ('/ χρήστης')
      .set ('Αποδοχή', 'εφαρμογή / json')
      .εξέταση (200, {
        id: '1',
        όνομα: 'John Math'
      }, Έγινε)
  })
})

Μπορείτε να ρωτήσετε: πώς καταγράφονται τα δεδομένα στη βάση δεδομένων που εξυπηρετεί το API REST;

Γενικά, είναι μια καλή προσέγγιση για να γράψετε τις δοκιμές σας με τέτοιο τρόπο ώστε να κάνουν όσο το δυνατόν λιγότερες υποθέσεις σχετικά με την κατάσταση του συστήματος. Παρ 'όλα αυτά, σε μερικά σενάρια μπορείτε να βρείτε τον εαυτό σας σε ένα σημείο όταν πρέπει να ξέρετε ακριβώς ποια είναι η κατάσταση του συστήματος ακριβώς, έτσι μπορείτε να κάνετε ισχυρισμούς και να πετύχετε υψηλότερη κάλυψη δοκιμών.

Έτσι, με βάση τις ανάγκες σας, μπορείτε να συμπληρώσετε τη βάση δεδομένων με δεδομένα δοκιμών με έναν από τους παρακάτω τρόπους:

  • εκτελέστε τα σενάρια δοκιμής σε μαύρο κουτί σε ένα γνωστό υποσύνολο δεδομένων παραγωγής,
  • συμπληρώστε τη βάση δεδομένων με επεξεργασμένα δεδομένα πριν από την εκτέλεση των δοκιμαστικών περιπτώσεων.

Φυσικά, οι δοκιμές με μαύρο κουτί δεν σημαίνει ότι δεν χρειάζεται να κάνετε δοκιμές μονάδων, θα πρέπει ακόμα να γράψετε δοκιμές μονάδων για τα API σας.

# 6: Να βασίζεται σε JWT, χωρίς έλεγχο ταυτότητας

Καθώς τα API REST πρέπει να είναι απασχολημένα, το ίδιο ισχύει και για το επίπεδο ελέγχου ταυτότητας. Για αυτό, το JWT (JSON Web Token) είναι ιδανικό.

Το JWT αποτελείται από τρία μέρη:

  • Header, που περιέχει τον τύπο του συμβόλου και τον αλγόριθμο κατακερματισμού
  • Ωφέλιμο φορτίο, που περιέχει τις αξιώσεις
  • Υπογραφή (το JWT δεν κρυπτογραφεί το ωφέλιμο φορτίο, απλά υπογράψτε το!)

Η προσθήκη πιστοποίησης βάσει JWT στην εφαρμογή σας είναι πολύ απλή:

const koa = απαιτούν ('koa')
const jwt = απαιτούν ('koa-jwt')
const app = koa ()
app.use (jwt ({
  μυστικό: 'πολύ μυστικό'
}))
// Προστατευμένο μεσαίο λογισμικό
app.use (λειτουργία * () {
  // το περιεχόμενο του διακριτικού θα είναι διαθέσιμο σε αυτό το .state.user
  this.body = {
    μυστικό: '42'
  }}
})

Μετά από αυτό, τα τελικά σημεία API προστατεύονται με JWT. Για να αποκτήσετε πρόσβαση στα προστατευμένα τελικά σημεία, πρέπει να δώσετε το διακριτικό στο πεδίο κεφαλίδας εξουσιοδότησης.

curl - header "Εξουσιοδότηση: Φορέας eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMNNTY3ODkwI
iwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30
RMHrHDcEfxjoYZgeFONFh7HgQ "my-website.com

Ένα πράγμα που θα μπορούσατε να παρατηρήσετε είναι ότι η ενότητα JWT δεν εξαρτάται από οποιοδήποτε επίπεδο βάσης δεδομένων. Αυτό συμβαίνει επειδή όλα τα μάρκες JWT μπορούν να εξακριβωθούν μόνα τους και μπορούν επίσης να περιέχουν χρόνο για να ζήσουν αξίες.

Επίσης, πρέπει πάντοτε να βεβαιωθείτε ότι όλα τα τελικά σημεία API σας είναι προσβάσιμα μόνο μέσω ασφαλούς σύνδεσης χρησιμοποιώντας το HTTPS.

Σε ένα προηγούμενο άρθρο, εξηγήσαμε λεπτομερώς τις μεθόδους ελέγχου ταυτότητας ιστού - σας συνιστώ να το ελέγξετε!

# 7: Χρησιμοποιήστε αιτήματα υπό όρους

Υποχρεωτικά αιτήματα είναι αιτήσεις HTTP που εκτελούνται διαφορετικά ανάλογα με συγκεκριμένες κεφαλίδες HTTP. Μπορείτε να σκεφτείτε αυτές τις κεφαλίδες ως προϋποθέσεις: αν πληρούνται, οι αιτήσεις θα εκτελούνται με διαφορετικό τρόπο.

Αυτές οι κεφαλίδες προσπαθούν να ελέγξουν αν μια έκδοση ενός πόρου που είναι αποθηκευμένη στον διακομιστή αντιστοιχεί σε μια συγκεκριμένη έκδοση του ίδιου πόρου. Για το λόγο αυτό, οι κεφαλίδες αυτές μπορούν να είναι:

  • το χρονικό σημάδι της τελευταίας τροποποίησης,
  • ή μια ετικέτα οντότητας, η οποία διαφέρει για κάθε έκδοση.

Αυτές οι κεφαλίδες είναι:

  • Τελευταία τροποποιημένη (για να υποδείξει πότε ο πόρος τροποποιήθηκε τελευταία),
  • Etag (για να υποδείξει την ετικέτα οντότητας),
  • If-Modified-Since (χρησιμοποιείται με την τελευταία τροποποιημένη κεφαλίδα),
  • If-None-Match (χρησιμοποιείται με την κεφαλίδα Etag),

Ας ρίξουμε μια ματιά σε ένα παράδειγμα!

Ο παρακάτω υπολογιστής δεν είχε προηγούμενες εκδόσεις του πόρου doc, επομένως ούτε η κεφαλίδα If-Modified-Since ούτε η κεφαλίδα If-None-Match εφαρμόστηκαν κατά την αποστολή του πόρου. Στη συνέχεια, ο διακομιστής ανταποκρίνεται με σωστά τις κεφαλίδες Etag και Last-Modified.

Από την τεκμηρίωση των αιτημάτων MDN υπό όρους

Ο υπολογιστής-πελάτης μπορεί να ορίσει τις κεφαλίδες If-Modified-Since και If-None-Match μόλις προσπαθήσει να ζητήσει τον ίδιο πόρο - αφού έχει τώρα μια έκδοση. Εάν η απάντηση θα ήταν η ίδια, ο διακομιστής απλώς αποκρίνεται με την κατάσταση 304 - Δεν έχει τροποποιηθεί και δεν στέλνει ξανά τον πόρο.

Από την τεκμηρίωση των αιτημάτων MDN υπό όρους

# 8: Αγκαλιάστε το όριο

Ο περιορισμός του ποσοστού χρησιμοποιείται για τον έλεγχο του αριθμού των αιτημάτων που ένας συγκεκριμένος καταναλωτής μπορεί να στείλει στο API.

Για να πείτε στους χρήστες του API πόσα αιτήματα έχουν απομείνει, ορίστε τις ακόλουθες κεφαλίδες:

  • X-Rate-Limit-Limit, ο αριθμός των αιτήσεων που επιτρέπονται σε ένα δεδομένο χρονικό διάστημα
  • X-Rate-Limit-Remaining, ο αριθμός των αιτήσεων που παραμένουν στο ίδιο διάστημα,
  • X-Rate-Limit-Reset, ο χρόνος κατά τον οποίο θα επαναρυθμιστεί το όριο ρυθμού.

Τα περισσότερα πλαίσια HTTP το υποστηρίζουν από το κουτί (ή με plugins). Για παράδειγμα, εάν χρησιμοποιείτε το Koa, υπάρχει το πακέτο koa-ratelimit.

Σημειώστε ότι το χρονικό παράθυρο μπορεί να ποικίλει με βάση διαφορετικούς παροχείς API - για παράδειγμα, το GitHub χρησιμοποιεί μια ώρα για αυτό, ενώ το Twitter 15 λεπτά.

# 9: Δημιουργήστε μια σωστή τεκμηρίωση API

Γράφετε APIs ώστε άλλοι να μπορούν να τα χρησιμοποιήσουν, να επωφεληθούν από αυτά. Η παροχή τεκμηρίωσης API για τα API REST Node.js σας είναι ζωτικής σημασίας.

Τα παρακάτω έργα ανοιχτού κώδικα μπορούν να σας βοηθήσουν στη δημιουργία τεκμηρίωσης για τα API σας:

  • API Blueprint
  • Κομπάζω

Εναλλακτικά, αν θέλετε να χρησιμοποιήσετε ένα φιλοξενούμενο προϊόν, μπορείτε να πάτε για το μελισσοκομείο.

# 10: Μην χάσετε το μέλλον των API

Τα τελευταία χρόνια δημιουργήθηκαν δύο μεγάλες γλώσσες ερωτημάτων για τα API - συγκεκριμένα το GraphQL από το Facebook και το Falcor από το Netflix. Αλλά γιατί τους χρειαζόμαστε ακόμη;

Φανταστείτε το ακόλουθο αίτημα RESTful resource:

/ org / 1 / space / 2 / docs / 1 / συνεργάτες;
include = email & σελίδα = 1 & όριο = 10

Αυτό μπορεί να αποσυρθεί εύκολα - όπως θα θέλατε να έχετε την ίδια μορφή απάντησης για όλα τα μοντέλα σας όλη την ώρα. Αυτό είναι όπου η GraphQL και η Falcor μπορούν να βοηθήσουν.

Σχετικά με το GraphQL

Το GraphQL είναι μια γλώσσα ερωτήματος για τα API και ένα χρόνο εκτέλεσης για την ικανοποίηση αυτών των ερωτημάτων με τα υπάρχοντα δεδομένα σας. Το GraphQL παρέχει μια πλήρη και κατανοητή περιγραφή των δεδομένων στο API σας, δίνει στους πελάτες τη δυνατότητα να ζητούν ακριβώς τι χρειάζονται και τίποτα περισσότερο, καθιστά ευκολότερη την εξέλιξη API με την πάροδο του χρόνου και επιτρέπει ισχυρά εργαλεία ανάπτυξης. - Διαβάστε περισσότερα εδώ.

Σχετικά με την Falcor

Η Falcor είναι η καινοτόμος πλατφόρμα δεδομένων που εξουσιοδοτεί τους Netflix UIs. Το Falcor σάς επιτρέπει να μοντελοποιήσετε όλα τα δεδομένα backend σας ως ένα ενιαίο αντικείμενο Virtual JSON στο διακομιστή σας κόμβου. Στον πελάτη, εργάζεστε με το απομακρυσμένο αντικείμενο JSON χρησιμοποιώντας γνωστές λειτουργίες JavaScript όπως λήψη, ρύθμιση και κλήση. Εάν γνωρίζετε τα δεδομένα σας, γνωρίζετε το API σας. - Διαβάστε περισσότερα εδώ.

Καταπληκτικά API REST για έμπνευση

Εάν πρόκειται να αρχίσετε να αναπτύξετε ένα API REST Node.js ή να δημιουργήσετε μια νέα έκδοση παλαιότερης, έχουμε συλλέξει τέσσερα παραδείγματα πραγματικής ζωής που αξίζει να τα ελέγξετε:

  • GitHub API
  • Twilio API
  • API Stripe
  • API DigitalOcean

Ελπίζω ότι τώρα έχετε καλύτερη κατανόηση του τρόπου με τον οποίο πρέπει να γραφούν τα API χρησιμοποιώντας το Node.js. Παρακαλώ με ενημερώστε στα σχόλια αν χάσετε τίποτα!

Αρχικά δημοσιεύθηκε στο blog.risingstack.com στις 21 Φεβρουαρίου 2017.