Pergunta

Um monte de quadros usar convenções de URL como /controller/action/{id} que é ótimo, mas se você precisar de qualquer configuração, além disso, é até que você escreva suas próprias rotas.

Como é que você lida com URLs como /users/{id}/friends no backend? (A lista de todos os amigos de um usuário)

Eu estou pensando que no controlador, algo como isto seria apropriado:

class User {
    function index() {
        echo 'user index';
    }
}

class Friend extends User {
    function index($user_id) {
        echo 'friend index';
    }    
}

Em seguida, você teria o seguinte mapa:

/users              -> User::index()
/users/{id}         -> User::view($id)
/users/{id}/friends -> Friend::index($user_id)

Eu queria colocar a classe amigo dentro da classe de usuários, mas aparentemente você não pode fazer isso em PHP assim que este é o melhor que eu poderia vir acima com. Pensamentos?

O URL usaria para editar sua lista de amigos? /users/{id}/friends/edit poderia funcionar, mas não parece apropriado, já que você nunca deve estar editando lista de amigos de outra pessoa. Seria /account/friends/edit ser uma escolha melhor? Onde você colocar o código correspondente para isso? Em um controlador de amigo, ou um controlador de usuário, ou um controlador de conta especializado?

Bônus pergunta: o que você prefere? /photos/delete/{id} ou /photos/{id}/delete


As respostas:

Então, o que eu recolhi a partir das respostas é que se a "coisa" é complicado (como "amigos"), mas não tem o seu próprio controlador, você pode dar-lhe um sem um modelo, ou se não é , você deve enchê-lo com tudo o que está mais estreitamente relacionado. URLs não deve influenciar onde você colocar o seu código. A maioria das pessoas parecem pensar que você deve furar a /controller/action/{id} whever possível, porque é o que as pessoas estão familiarizados.

Ninguém realmente comentou sobre a classe estendida para além de dizer que é "estranho". Talvez friendlist teria sido uma classe mais adequado, nesse caso, se eu realmente queria separar-lo.

Obrigado por todas as respostas:)

Foi útil?

Solução

As rotas que você está falando, e do jeito que você está usando subclasses para alcançar esta estrutura, parece um pouco estranho para mim. A convenção padrão de /controller/action/{id} funciona muito bem para ações simples, mas se você estiver criando um aplicativo complexo você sempre precisará criar rotas personalizadas. Há provavelmente algumas boas diretrizes para usar ao criar estas rotas, mas realmente se resume a ficar consistente em toda a sua aplicação e manter as coisas o mais simples possível.

Eu não vejo nenhuma boa razão para ter mapeamento /user/{id}/friends a um controlador "Friend". Porque não basta ter "friends" ser uma ação no controlador User? Uma vez que você realmente drill down para visualizar a página de um amigo específico, você pode usar um controlador Friend (/friends/view/123) ou você pode redirecionar seu controlador User para que ele funcione para um amigo ou o usuário conectado no momento (/user/view/123).

Re:. A pergunta bônus, eu ia ficar com /photos/delete/{id} (/controller/action/{id}) já que é o mecanismo mais amplamente aceito

Outras dicas

Eu preferiria /photos/{id}/delete. Meu raciocínio é que se você tomar um componente fora da extremidade de um URL, ele ainda deve fazer sentido.

É muito fácil supor que /photos/{id} deve fazer:. Visualizar o conjunto de fotos para que {id}

Mas o que deveria /photos/delete fazer? Isso é muito claro.

Eu sei que há uma espécie de convenção padrão de /controller/action/id, mas que a organização é para o bem de mapeamento para a arquitetura de classe / método de controladores. Eu não acho que é uma boa idéia para organizar a interface do usuário para acomodar o código (o URL está em uma parte caminho do UI).


comentários Re: Sim, /photos/{id} talvez faz mais sentido para ver uma determinada foto pelo seu id. /users/{id}/photos talvez para ver uma coleção. Você decide.

O ponto é que você deve pensar da interface do usuário em termos de usuários, não em termos de organização de código.

Você pode fazer ou. O problema é quando você mistura os dois. / users / {id} / amigos e / usuários / amigos / {id} Quando alguém tem o id de "amigos" isto irá falhar. Isto pode parecer um caso trivial, mas é muito popular para usar nomes de usuário para ids. Você terá que nomes de usuário limite para cada ação.


Às vezes você não pode fazer /{controller}/{action}/{id}

Eu fiz um site de música indie um tempo atrás e fizemos

/artist/{username}
/artist/{username}/albums
/artist/{username}/albums/{album}

Nós não queria teste para condicionais para que não faça

/artist/{username}/{album}

Uma vez que não querer verificar para qualquer pessoa com um álbum chamado "álbuns"

Nós poderíamos ter feito isso

/artist/{username}
/artist/{username}/albums
/albums/{album}

mas então nós perderíamos a vantagem SEO de ter tanto o nome do artista e o nome do álbum na URL. Também neste caso estaríamos forçando nomes de álbuns para ser único, que seria ruim, já que é comum para artista a ter nomes de álbuns da mesma forma que outro artista.

Você poderia fazer /{controller}/{action}/{id} pura, mas, em seguida, você iria perder algum SEO e você não pode fazer de encurtamento de URL.

/artist/view/{username}
/artist/albums/{username}
/album/view/{album}

Voltando ao seu exemplo.

/ users / {id} / amigos / editar poderia trabalhar, mas não parece adequado, uma vez que você nunca deve estar editando alguém A lista de amigos de outra pessoa.

Neste caso, deve ser /friends/edit desde a sua identificação de usuário é a informação duplicado assumindo que o seu em uma sessão de alguma forma. Em geral, você quer URL apoio encurtando expansão não URL.

(Bônus pergunta) Nem, eu usaria RESTO . DELETE /photo?id={id}

Ele também depende de como você está armazenando seus dados. Eu poderia imaginar em alguns casos, você precisa de um 'amigo-list' para ser uma entidade em seu modelo. Uma abordagem lógica seria, então, para especificar um identificador único para cada lista de amigo, uma chave primária.

Este seria logicamente resultar na seguinte rota, como você só precisa de uma chave primária da lista de amigo para editar ou apagá-lo ...

/friends/edit/{friendListId}

É até você para decidir. Como pix0r declarou: convenção para pequenas aplicações é /{controller}/{action}/{id} onde {id} deve ser opcional para combinar com a maioria de suas ações sites. Em alguns casos aplicações ficar grande e você quiser definir rotas específicas com mais de 3 elementos. Em alguns casos, certas entidades, é só pegar um significado maior (exemplo acima) e você pode decidir definir um controlador personalizado para ele (que faz o perfeito rota padrão outra vez ...).

Eu ia ficar com o /controller/action/id rota padrão, mas simplesmente não começar a fazer os controladores para tudo (como amigos) no começo. O padrão MVC torna muito fácil para você rotas mudança mais tarde , desde que todas as suas rotas-links e ações (formulários etc.) são gerados com base em rotas e ações. Então, você realmente não tem que se preocupar muito:)

As URLs si realmente não importa muito. O que é mais importante é o que se passa em cada um dos controladores. No seu exemplo você tinha sua lista de amigos estender a classe User. Se a sua lista de amigos é realmente apenas uma lista de usuários, talvez ele deve estender o controlador Users para que você lidar com listas de usuários em um só lugar.

class Users {

    public function index() {
        $users = $this->findUsers();
    }

    protected function findUsers($userId=null) { ... }
}

class Friends extends Users {

    public function index($userId) {
        $users = $this->findUsers($userId);
    }
}

Se você tem um tempo difícil descobrir qual classe para estender escrever o que você precisa de cada uma das classes e escolher aquele com a maior lista.

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