Ruby Grape JSON-über-HTTP-API, benutzerdefinierte JSON-Darstellung

8

Ich habe eine kleine Prototyp-Unterklasse von Grape::API als Rack-Dienst und verwende Grape::Entity , um die internen Objekte meiner Anwendung darzustellen.

Ich mag die Grape::Entity DSL, habe aber Probleme herauszufinden, wie ich über die Standard-JSON-Darstellung hinausgehen sollte, die für unsere Zwecke zu leicht ist. Ich wurde gebeten, eine Ausgabe im Format "jsend oder ähnlich" zu produzieren: Ссылка

Ich bin mir überhaupt nicht sicher, welche Art der Veränderung am meisten mit dem Rahmen der Traube im Einklang steht (ich möchte hier einen Weg des geringsten Widerstands). Sollte ich einen benutzerdefinierten Grape Formatierer erstellen (ich habe keine Ahnung, wie man das macht), neue Rack Middleware (ich habe dies getan, um API Ins / Outs über SysLog zu protokollieren - aber Formatierung scheint schlecht wie ich Wollte den Körper von JSON zurück analysieren, um Container-Ebene hinzuzufügen, oder von Grape::Entity zu zB wechseln RABL?

Beispielcode ("app.rb")

%Vor%

Rackup-Datei ("config.ru")

%Vor%

Ich starte es:

%Vor%

Und rufe es an:

%Vor%

Was ich gerne sehen würde:

%Vor%

Offensichtlich könnte ich einfach etwas tun wie

%Vor%

in jeder Route - aber das scheint nicht sehr trocken. Ich bin auf der Suche nach etwas saubererem und weniger offen zum Ausschneiden und Einfügen von Fehlern, wenn diese API größer wird und vom gesamten Team gepflegt wird.

Komischerweise, wenn ich { :status => "success", :data => present( thing, :with => ThingPresenter ) } mit grape 0.3.2 probierte, konnte ich es nicht zum Laufen bringen. Die API hat nur den Wert von present zurückgegeben - hier ist mehr los als ursprünglich angenommen.

    
Neil Slater 19.03.2013, 11:22
quelle

5 Antworten

14

Dies ist, was ich am Ende durch eine Kombination aus dem Lesen der Grape-Dokumentation, Googeln und Lesen einiger Pull-Requests auf GitHub endete. Nachdem ich das :json -Format deklariert habe (um alle anderen Standard-Goodies zu erhalten), überliste ich die Ausgabeformatierer mit neuen, die jsends Wrapperlayer hinzufügen. Das Ergebnis ist viel sauberer als der Versuch, Grapes #present helper (der Fehler nicht gut abdeckt) oder eine Rack-Middleware-Lösung (die Deserialisierung und Neuserialisierung von JSON erfordert und zusätzlich viel Code benötigt) zu umbrechen Fehler abdecken).

%Vor%     
Neil Slater 19.03.2013, 14:55
quelle
2

Ich glaube, damit wird erreicht, was Ihr Ziel ist, wenn Sie grape

verwenden %Vor%     
abc123 09.05.2014 20:24
quelle
1

Sie könnten dafür eine Middleware-Ebene verwenden. Grape hat ein Modul Middleware::Base , das Sie für diesen Zweck verwenden können. Meine nicht so super schöne Umsetzung:

%Vor%

Und in der Klasse MainService würden Sie eine Zeile hinzufügen: use ::StatusAdder

    
Kashyap 19.03.2013 14:01
quelle
1

Aus heutiger Sicht glaube ich, dass der richtige Weg, dies mit Grape zu tun, ist:

%Vor%     
henry74 01.10.2013 02:09
quelle
1

Ich benutze @ Neil-Slaters Lösung mit einer zusätzlichen Modifikation, von der ich dachte, dass sie andere nützlich finden könnten.

Mit nur einem rescue_from :all wird das Ergebnis für allgemeine 404 Fehler als 403 Forbidden zurückgegeben. Außerdem lautet der Status "error", wenn es "fail" sein sollte. Um diese Probleme zu beheben, habe ich einen Rescue-Handler für RecordNotFound hinzugefügt:

%Vor%

note - Ich konnte den richtigen Zugriff auf das Rack env nicht herausfinden, so dass Sie sehen können, dass ich es als Nullwert übergebe (was in Ordnung ist, da der Fehlerhandler das nicht tut) benutze den Wert).

Ich nehme an, Sie könnten diesen Ansatz weiter ausweiten, um die Verarbeitung von Antwortcodes weiter zu verfeinern. Für mich bestand der schwierige Teil darin, dass ich ein Rack::Response -Objekt benötigte, an das ich die formatierte Fehlermeldung weitergeben konnte.

    
Andrew Chase 05.12.2013 23:16
quelle

Tags und Links