É essa maneira correta de lidar com RESTful como URL na estrutura de elevador?

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

  •  19-09-2019
  •  | 
  •  

Pergunta

Se eu tenho um URL como http: // localhost/test/edit/{id} e eu gostaria que o {id} se transforme em um parâmetro em vez da parte do caminho do URL.

É a melhor maneira de fazer isso criando um menu com rewriterequest? Porque eu achei um pouco de caldeira se eu tiver muito padrão de URL como esse.

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")) -> ()

    })
})
Foi útil?

Solução

No seu boot.scala, você precisa do seguinte (a partir do código de trabalho real!) Observe que cada caminho de reescritor de resposta deve estar no seu sitemap.

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))
}

Outras dicas

Obrigado por todas as suas respostas.

O que eu mais quero é que essas coisas reescrevem bem combinadas com o menu, para que eu pudesse configurá -las apenas na minha aula de modelo, como a característica crudificada.

No final, criei uma subclasse do LOC para lidar com essas regras de reescrita e achei que funciona muito bem e tornar as coisas muito mais simples (pelo menos para mim), então posto o código aqui.

Sinta -se à vontade para copiar isso se alguém precisar

/**
 *  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) -> ()
        }
    })
}

Eu tropecei neste post porque tinha a mesma pergunta. A resposta de Jim Barrows está correta (e a mais fácil), mas sem nenhuma explicação, foi difícil para mim entender o que esse código está fazendo. Uma explicação detalhada de por que a solução de Jim funciona pode ser encontrada no Livro do Lift Online (http://groups.google.com/group/the-lift-book). Confira a Seção 3.12, intitulado "URL Rewriting", que o leva a passo a passo sobre como construir um URL repousante.

De qualquer forma, não deve haver necessidade de escrever um LOC personalizado para alcançar o efeito desejado.

Boa sorte!

Desculpe, o comentário acima é um Liitle bagunçado.

O problema é que, se eu tiver um modelo chamado Edit.html em WebApp/Test, que é o modelo que eu uso para editar um item.

E eu tenho uma instância de menu como o seguinte:

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

Só corresponderia ao URL como http: // localhost/teste/edição, nada como http: // localhost/test/edit/1

Por que você deseja alterá -lo para consultar param? É por razões técnicas ou de estrutura?

O {id} pertence à minha opinião ao caminho URI, identifica um recurso exclusivo e eu gosto de manter essas informações dentro do caminho. Os URIs podem ser qualquer tipo de sequência de caracteres (para que o parâmetro de consulta também funcionasse), mas eu modelaria os URIs o mais próximo possível do ID de recursos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top