2017-06-16 5 views
0

Diese Frage wurde bereits 2010 gestellt, aber ich denke, dass es heute eine bessere Antwort geben könnte. Grundsätzlich muss ich eine Art von Objekt speichern und auf jede Anfrage zugreifen, idealerweise möchte ich in der Lage sein, das Objekt innerhalb einer Anfrage zu ändern (ich denke, ein MVar oder IORef wird dafür tun). Das Snaplet-Tutorial scheint zu zeigen, dass es möglich ist, aber es erklärt hauptsächlich, wie Snaplets zu verwenden sind (das ist, wofür das Tutorial eigentlich ist), und erklärt nicht wirklich, wie dieses "App" -Objekt funktioniert oder sogar gespeichert wird . Ich habe keine Ahnung, wie ich das auf meinen Fall anwenden soll, wo ich keine Snaplets brauche (ich mache eine API, also brauche ich nicht einmal Heist).Wie speichere ich ein Objekt serverseitig mit Snap Framework?

So den Standardcode gegeben:

site :: Snap() 
site = do 
    ifTop (writeBS "hello world") <|> 
    route [ ("stuff/:param", someHandler) ] <|> 
    dir "static" (serveDirectory ".") 

Wie ändere ich das „Register“ ein Objekt irgendwo, dass ich in someHandler verwenden könnte? Die Antwort von 2010 ist nur, es teilweise auf jeden Handler anzuwenden, was funktionieren würde, aber das Snaplet-Tutorial lässt mich glauben, dass es einen besseren Weg geben muss.

+0

Können Sie einen Link zu der Antwort hinzufügen, auf die Sie sich beziehen? –

+0

Oh ja, sorry: https://stackoverflow.com/questions/3903205/how-do-i-maintain-a-server-side-state-with-snap-framework – Ulrar

+0

Fast alle der Fangfunktionen Rückgabetyp haben ' MonadSnap m => .. -> mX'. Also mache einfach eine Instanz 'MonadSnap m => MonadSnap (ReaderT m)' (falls es noch nicht existiert) und du musst die Umgebung nicht explizit weitergeben. – user2407038

Antwort

0

Im Abschnitt „Arbeiten mit State“ in der snaplet Tutorial sie erklären, wie mit dem lokalen Zustand zu arbeiten. Wenn Sie sich den zweiten Codestück im darüber liegenden Abschnitt "Snaplet-Übersicht" ansehen, können Sie sehen, wie sie den Zustand einrichten, wenn sie den Datentyp dafür mit Lens initialisieren.

Nicht sicher, wie vertraut Sie mit diesen Dingen sind, aber Lens können Sie zugreifen (dh lesen/schreiben/anpassen) Stücke von Daten innerhalb größerer Werte. Der gesamte Status des Servers wird in diesem Fall als ein Datenblock dargestellt (ein Datensatztypwert), der initialisiert wird, wenn sich der Server befindet.

Hinweis: _companyName :: IORef B.ByteString < - ist ein Stück Staat, den Sie im Beispiel mutieren können, und im Abschnitt "Arbeiten mit Zustand", das ist genau das, was sie tun. Sie haben ein Beispiel, das einen HTTP GET oder POST zu dieser URL annimmt und entweder mit dem neuen "Name" -Param (POST) aktualisiert und den neuen Status zurückgibt, oder wenn es ein GET ist, gibt es nur den aktuellen Status zurück.

+0

Alles klar also im Grunde musst du deine ganze App zu einem Snaplet machen um einen Zustand zu bekommen, wenn ich das richtig verstehe. Scheint zu arbeiten, ich gehe davon aus, dass das keine Auswirkungen auf die Performance haben wird, da ich keine Snaplets benutze, nur die eine? Nicht, dass es in meinem Fall sehr wichtig ist, nur neugierig – Ulrar

+0

Mein Verständnis von Snap ist, seit einer bestimmten Version, ** alles ** ist mit Snaplets, die die Basis-Ebene Abstraktion für jede Anwendung-Programmierer Ebene Bedenken gebaut werden. Dies bietet Modularität und ist sehr effizient. Objektive sind extrem leichte Datenzugriff auf Datensätze, die auch sehr einfach sind. Snaplets sind in ihrem Kern über den Status, also wäre dies der kanonische Weg, um einen Status in Ihre Snap-Anwendung zu bekommen. Es ist schnell und effizient, von meinem Verständnis her, aber warum nicht ein paar Profiling :) –

Verwandte Themen