Τον τελευταίο καιρό έχω αρχίσει να ασχολούμε με Web Services, λόγω μιας ανάγκης που υπήρξε από έναν πελάτη για να του παρέχουμε την δυνατοτητα να φτιάξει Web Site που να αξιοποιούν το back office της εφαρμογής μας.
Όμως λόγω του μεγάλου πλήθους των λειτουργιών που παρέχει η εφαρμογή, έπρεπε να βρούμε έναν γενικό τρόπο ώστε να κάνουμε αξιοποιήσιμη όλη αυτή την λειτουργικότητα. Επίσης έπρεπε να μην γινει τελειως γενικά, γιατι αυτός που θα χρησιμοποιεί το back office μέσω Web Services θα πρέπει να έχει κάποιους περιορισμους. Οπότε καταλήξαμε στην δημιουργία ενός επιπέδου facade. Δηλαδή κλάσεων που έχουν μεθόδους που κάνουν κάτι το ολοκληρωμένο, πχ αναζήτηση διαθέσιμων ξενοδοχείων, ώστε να χρησιμοποιηθούν για τα Web Services 1:1. Οπότε το μονο που μας χρειαζοτανε ήταν ένας τρόπος να καλούμε αυτές τις μεθόδους.
Αρχικά όλες οι μέθοδοι χρησιμοποιούσαν primitive τύπους, δηλαδή String, Double, Boolean, Date, αλλά αυτό δεν ήταν αρκετό. Χρειαζόμασταν και σύνθετα αντικείμενα που χρησιμοποιούμε στο back office, όπως για παραδειγμα το αντικείμενο Customer. Το οποίο υπήρχαν δύο τρόποι να το παρουμε σε ένα Web Service, ο ένας ήταν να δημιουργήσουμε xsd που να το περιγραφει ως ComplexType, το οποίο θα σήμαινε ότι πολύ δύσκολα θα μπορούσαμε να το αλλάξουμε από την στιγμή που θα το δώσουμε στον πελάτη, ενώ ο άλλος ήταν να το παρουσιάσουμε ως ένα Map
Οπότε έπρεπε να βρούμε μια τυποποιηση που να υποστηρίζει τους εξείς τύπους: String, Double, Boolean, Date, Map, List, byte[]. Εξεταστηκαν διαφορα αλλά θέλαμε κάτι που να μην ειναι αποκλειστικά Java, να μην έχει WSDL και τυποποιήσεις που σχεδον κανεις δε χρησιμοποιεί αλλά κάτι απλό που ο καθένας μπορεί να αξιοποιήσει, οπότε καταλήξαμε στο XML-RPC, για το οποίο υπάρχει μια υλοποιηση απο την Apache
Το XML-RPC είναι μια τυποποιηση που χρησιμοποιείται στα Web Services απο το 1999, πράγμα που την κάνει απόλυτα συμβατή με κάθε γνωστή γλώσσα προγραμματισμού. Επίσης η υλοποιηση της ειναι τόσο απλή και γενική που διευκολύνει, διοτι σε αφήνει να δημιουργήσεις ότι θέλεις χωρίς να χρειαστεί να χρησιμοποιήσεις ένα τεράστιο και δυσνοητο specification. Όπως συμβαίνει σε άλλα specs, που σου προσφέρουν την δυνατότητα να ειναι πιο κατανοητό το XML που χρησιμοποιείται για την επικοινωνία, αλλά από την άλλη έχει αρκετά περίπλοκο τρόπο να τα χρησιμοποιήσεις, σωστά. Η βασική ιδέα του XML-RPC είναι ότι ένα Web Service δεν ειναι τίποτα περισσότερο από ένα remote call, κάτι σαν αυτό που έκανε παλιά η CORBA και το RMI. Οπότε τα μονα που χρειάζονται είναι:
α) Παραμετροι ειδόσου+Όνομα Μεθοδου=αίτηση προς την υπηρεσία
β) Παραμετροι εξόδου ήΛάθος=απάντηση της υπηρεσίας
Εμεις προκειμένου να το κάνουμε ακόμα πιο εύκολο αποφασίσαμε ότι θα δεχόμαστε μονο μια παράμετρο εισόδου που θα είναι ένα Map, όπου κλειδι θα έχει το όνομα της παραμέτρου και τιμή την τιμή της. Οπότε έτσι καταφέραμε να έχουμε named parameters που σημαίνει ότι δεν υπάρχει θέμα σειράς, που ειναι κάτι που δε μπορείς εύκολα να ελέγχθει στα Web Services. Επίσης αποφασίσαμε, κατα αντιστοιχία, να έχουμε μονο μια παράμετρο εξόδου, πάλι Map.
Οποτε, ουσιαστικά ο τρόπος λειτουργίας είναι "περνάς ένα Map παραμέτρων σε μια μέθοδο που σου επιστρέφει ένα Map παραμέτρων, ή ένα λάθος". Πράγμα που απλοποιεί πάρα πολύ την δουλειά και του client. Οπου για λόγους testing έχει χρειαστει να υλοποιήσω. Αυτή η ύπαρξη του Map ως κυριου τύπου με οδήγησε στο να δημιουργήσω μια κλάση που ονομα "Mapable" όπου πολύ απλά φτιάχνω subclasses αυτής στην μεριά του Client και δημιουργώ εύκολα και γρήγορα το μοντέλο μου, απλά προσθέτω getters και setters που απλά κάνουν get και put σε ένα private Map
Βέβαια ακόμα το έχω σε πειραματικό στάδιο, αλλά πιστεύω ότι θα μπορούσε να φανει πολύ χρήσιμο να μην βάζεις private members αλλά να τα κρατας όλα σε ένα private Map.
ΥΓ: Οποιος ενδιαφέρετε ή έχει καποια επιπλέον ιδέα, πολύ ευχαρίστως να μου την γράψει.
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου