È questo modo corretto di gestire RESTful come URL nel quadro di sollevamento?

StackOverflow https://stackoverflow.com/questions/2036037

  •  19-09-2019
  •  | 
  •  

Domanda

Se ho un URL del tipo http: // localhost / test / modificare / {id} e Vorrei che la {id} trasformare ad un parametro invece di parte sentiero URL.

E 'modo migliore di farlo da creare un menu con RewriteRequest? Perché ho trovato un po 'boilerplate se ho molto modello URL come questo.

val menu = Menu(new Loc[Unit] {

    override def name = "Test"
    override def text = "Test"
    override def link = (List ("Test"), true)
    override def params = Nil
    override def defaultValue = Full(())


    def isTarget (path: ParsePath) = path match {
        case ParsePath (List("Test", "edit", id), _, _, _) => true

        case _ => false
    }

    override def rewrite = Full ( NamedPF("Test") {
        case RewriteRequest (path, _, _) if isTarget(path) => 
             RewriteResponse(List("Test", "edit"),  
                             Map("id" -> "1024")) -> ()

    })
})
È stato utile?

Soluzione

Nel vostro boot.scala sono necessarie le seguenti (dal codice effettivo di lavoro!) Si noti che ogni percorso RewriteResponse deve essere nella vostra mappa del sito.

LiftRules.rewrite.append {
  case RewriteRequest(ParsePath(List("shopInfo", "view", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "view" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "orders", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "orders" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "sync", id), _, _, _), _, _) => RewriteResponse("shopInfo" ::  "sync" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "delete", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "delete" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "edit", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "edit" :: Nil, Map("id" -> id))
}

Altri suggerimenti

Grazie per tutte le vostre risposte.

Quello che voglio di più è che queste cose di riscrittura combinati perfettamente con Menu, così ho potuto configurazione li solo nella mia classe del modello, come CRUDify trait.

Alla fine, ho creato una sottoclasse di Loc me stesso per gestire queste regole di riscrittura, e ho trovato che funziona abbastanza bene e rendere le cose molto più semplici (almeno per me), quindi inserisco il codice qui.

Sentitevi liberi di copiare questo se qualcuno ha bisogno

/**
 *  A RESTful-like URL handling Loc
 *
 *  If you have the following templates:
 *
 *    * webapps/item/edit.html
 *    * webapps/item/view.html
 *  
 *  You want the following URL map to corresponding template with 
 *  last path component as a S parameter.
 *
 *    http://localhost/item/edit/1  to  http://localhost/item/edit
 *    http://localhost/item/view/1  to  http://localhost/item/view
 *
 *  You could create a Menu with this Loc class in your Model object.
 *
 *  <code>
 *  object Item extends Item with LongKeyedMetaMapper[Item] 
 *  {
 *      // Other methods here...
 *
 *      def menu () {  
 *
 *          // What methods do we have?
 *          val methods = List ("view", "edit")
 *
 *          val parameterName = "itemID"
 *          val itemLoc = new RESTfulLoc("Item", List("item"), "Item", 
 *                                       methods, parameterName)
 *
 *          Menu (itemLoc)
 *      }
 *  }
 *  </code>
 *
 *  Now add the menu to SiteMap in Boot.boot
 *
 *  <code>
 *  class Boot {
 *      def boot () {
 *          
 *          val entries = Item.menu ::  Nil
 *
 *          LiftRules.setSiteMap(SiteMap(entries:_*))
 *      }
 *  }
 *  </code>
 *
 *
 *  Finally, You could access the parameter in your snippet with 
 *  S.param("itemID")
 *
 */
class RESTfulLoc (val name: String, val path: List[String],
                  val text: LinkText[Unit], val methods: List[String],
                  val parameterName: String,
                  val locParams: LocParam[Unit]*) extends Loc[Unit] 
{
    override val defaultValue = Full(())
    override val params = locParams.toList
    override val link: Link[Unit] = (List(path.first), true)

    def this (name: String, path: List[String], text: LinkText[Unit], 
              methods: List[String], locParams: LocParam[Unit]*) = 
    {
        this (name, path, text, methods, "id", locParams:_*)
    }

    private def isTarget (path: ParsePath) = 
    {
        path.partPath -- this.path match {
            case List (action, id) => {
                (methods contains action) && id != "index"
            }
            case _ => false
        }
    }

    override def rewrite = Full (NamedPF("RESTfulLoc") 
    {
        case RewriteRequest (path, _, _) if isTarget(path) => {
             val parameter = path.partPath.last
             val action    = path.partPath.init
             val data      = Map (parameterName -> parameter)

             RewriteResponse(action, data) -> ()
        }
    })
}

Mi sono imbattuto in questo post perché ho avuto la stessa domanda. La risposta da Jim Barrows è corretta (e il più facile), ma senza alcuna spiegazione è stato difficile per me di Grok ciò che il codice sta facendo. Una spiegazione dettagliata del motivo per cui le opere di soluzioni di Jim si trovano in ascensore servizio di prenotazione online ( http: / /groups.google.com/group/the-lift-book ). Scopri la sezione 3.12, dal titolo "la riscrittura degli URL", che ti guida attraverso step-by-step su come costruire un URL RESTful.

In ogni caso, non ci dovrebbe essere bisogno di scrivere una Loc personalizzato per ottenere l'effetto desiderato.

Buona fortuna!

Il commento di cui sopra è un disordinato: basterebbe.

Il problema è che se ho un modello denominato edit.html sotto webapp / Test, che è il modello che uso per modificare un elemento.

E ho un esempio di menu come il seguente:

Menu (Loc("Test", List("Test") -> true, "Test"))

Si sarebbe partita solo URL del tipo http: // localhost / test / modificare , non qualcosa di simile http: // localhost / test / modificare / 1

Perché si vuole cambiare per interrogare param? E 'per motivi tecnici o quadro?

La {id} appartiene a mio avviso, al percorso URI, identifica una risorsa unica e mi piace di mantenere queste informazioni all'interno del percorso. Gli URI possono essere qualsiasi tipo di stringa di caratteri (in modo da parametro di query potrebbe anche funzionare), ma vorrei modellare gli URI più vicino risorsa-id conforme possibile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top