2009-04-23 8 views
0

Ich schreibe gerade eine Web-Software, die auch von Client-Desktops über eine API verwendet wird. Das Problem, mit dem ich gerade konfrontiert bin, ist: Soll ich jede Aktion des Hinzufügens/Aktualisierens/Löschens von Objekten in der Anwendung zweimal implementieren? Einmal wie es im normalen Code sitzt und einmal für die API isoliert?Erstellen einer API für meine Software - Grundlegende Code-Struktur

Oder sollte ich lieber ein System von OOP-Modellklassen verwenden, die alle Objekte in meiner Datenbank darstellen und diese sowohl für die API als auch für den normalen Code verwenden?

Oder entwickeln Sie die API aus erster Hand und verwenden Sie sie auch von meiner normalen Weboberfläche?

Das ist etwas, über das ich mich immer gewundert habe. Danke im Voraus!

Antwort

3

Es ist fast immer eine schlechte Idee, Dinge zweimal zu tun - Sie sind wahrscheinlich besser dran, die API zu implementieren, sie für den Endbenutzer zu öffnen und sie auch für den Client-Code zu verwenden, mit zusätzlichen Haken für Zeug, das Interface-spezifisch ist.

+0

Das war mein Problem auch. Aber was würde ich dann in der normalen Anwendung verwenden? Es wird sein: Hauptanwendung (im Internet) Dies ist über die API mit den Desktop-Anwendungen verknüpft. Oder sollte ich die API als Schnittstelle zur Datenbank behandeln und meine Webanwendung verwendet auch die API zum Abrufen und Abrufen von Daten? –

+0

Sie würden definitiv für den zweiten Ansatz gehen. Wenn Sie das Modell von den anderen Komponenten entkoppeln können, können Sie ein Web-Interface (fast) so einfach wie ein winforms-Interface verwenden. – em70

+0

Ganz zu schweigen davon, wenn Sie später einen Refactoring durchführen müssen, können Sie all dies unter dem Deckmantel der API tun und nur neue Felder offenlegen - wenn Sie mit einer eng gekoppelten Schnittstelle arbeiten, wird die Funktionalität viel mehr schmerzlich. –

2

Deshalb haben wir die REST (und SOAP) Protokolle.

Der Desktop stellt RESTful-Anfragen an Ihre Webanwendung. Ihre Webanwendung empfängt die REST-Anforderungen und erledigt die eigentliche Arbeit.

Ihr Code existiert an genau einem Ort - dem Web.

2

Zunächst möchte ich sagen, dass meine Erfahrung mit Django ist, das ein reichhaltiges Web-Framework ist, das bereits ein ORM bietet. Ich muss Modelle erstellen, um meine Objekte zu repräsentieren. Ich führe keine rohe SQL aus.

So natürlich würde ich Ihren zweiten Ansatz empfehlen. Auf Anhieb werde ich sagen, dass Ihr dritter Ansatz Kopfschmerzen bereiten wird. Warum? Weil Sie verschiedene Nachbearbeitungen machen wollen. Das ist die Natur des Spiels. Wenn Sie eine CRUD-Schnittstelle im Internet einrichten, werden einige Dinge als Felder in Ihrem Modell gespeichert, die der Benutzer nicht einmal von der CRUD-Seite aus erkennen würde. Als Beispiel habe ich eine CRUD-Seite für Nachrichten, die mit verschiedenen Unternehmen verknüpft sind. (Dies ist ein Datenbank-Fremdschlüssel.) Dies wird natürlich automatisch durch Login-Informationen bereitgestellt. Aber der Prozess für die Anmeldung an der Webseite (und wo diese Anmeldung gespeichert wird) unterscheidet sich sehr von dem für eine Remote-API.

Meine Präferenz ist es, ein bisschen von Ihren ersten zwei Ansätze zu kombinieren. Es sollte definitiv Aktionen geben, die jedes Mal auftreten sollten, wenn ein Objekt gespeichert wird. Setzen Sie diese in eine save() Methode (oder update() und insert(), wenn Sie die Dinge ein wenig mehr brechen wollen). Sie sollten nicht darüber nachdenken, diese Funktionalität zweimal zu implementieren.

Es gibt jedoch Deserialisierung/Objektkonstruktion und Validierung, die in der Webschnittstelle und der Remote-API unterschiedlich auftreten. Dies sollte wirklich separat implementiert werden.

Man könnte sich auch die Validierung als von der Deserialisierung inhärent unterscheiden und bedenken, dass einige Regeln gleich und andere unterschiedlich sind. Zum Beispiel weiß ich in einer Webschnittstelle, dass ich, wenn ich die Geschichte erhalte, die modification_time selbst stemple, während ich für eine Remote-API dem Kunden vertraue, die Zeit zu stempeln. Dies ist beabsichtigt. Auf der anderen Seite, jede Geschichte, die keine Tags darauf hat, muss ein default Tag erhalten, unabhängig davon, woher es kommt. Vielleicht bevorzugen Sie die Freiheit, die Validator-Objekte nach der Objektkonstruktion einfach einstecken zu lassen.

ein Codebeispiel (in Python):

def handle_remote_update(serialized_object): 
    #do some parsing 
    model_object = ModelObject(...)#fill in with parsed values 
    validator1.validate(model_object) 
    validator3.validate(model_object) 
    model_object.save()#All database code is in this method 
    #If you have to log to your system or notify listeners, that's also in this method 

def handle_web_submission(post_dict): 
    #do some parsing 
    model_object = ModelObject(...)#fill in with parsed values 
    validator2.validate(model_object)#This wasn't executed above 
    validator3.validate(model_object)#This was 
    model_object.save()#Same code gets executed down here as above 

Zugegeben, habe ich behandelt nur den Fall von insert oder möglicherweise update. Was Sie brauchen Anruf diese Funktionen ist eine Methode Splitter, etwas, das weiß, wenn die Remote-API ruft insert gegenüber delete und ruft eine andere Funktion entsprechend (und ebenso für das Web-Interface). Wenn Sie ein Webframework verwenden, ist dies möglicherweise Ihr urlconfig für den Webschnittstellenteil.

1

REST hat sich zu einem Standard für die Bereitstellung einer API über das Internet für die Clients entwickelt und bietet Ihnen viel Flexibilität. Wenn Sie an der .net-Plattform arbeiten, können Sie ASTORIA [ADO.Net Data Services] verwenden, die Ihren REST-basierten Webservice generiert, indem Sie einfach Ihre Datenbankobjekte zuordnen.

+0

Haben Sie nicht von WCF gehört? –