APIs de descanso - desafios específicos para dispositivos móveis


25

Estou trabalhando em um novo projeto de aplicativo para iOS, no lado móvel. Algumas mudanças na arquitetura estão acontecendo e, por acaso, teremos que confiar em uma API privada customizada que será usada pelo aplicativo que estamos construindo e também por outros clientes, como um site.

A API que está sendo projetada segue o estilo Restante de operações URI e CRUD centradas em recursos mapeadas para verbos HTTP. coisas como:

GET www.example.com/books
DELETE www.example.com/books/482094
POST www.example.com/users/6793

O problema é que esse estilo geralmente leva à necessidade do cliente móvel fazer muitas solicitações para carregar uma única tela de aplicativo ou gerenciar uma ação de interface do usuário de usuário único. Isso faz com que o aplicativo fique no modo de carregamento por 8 segundos até ter tudo o que é necessário. Um aplicativo lento e sem resposta.

Os clientes móveis têm sérias limitações quando se trata de conectividade e, idealmente, devemos seguir esse tipo de regra:

1 tela == 1 chamada de API

1 gravação == 1 chamada de API.

Existem muitas situações em que isso o coloca em rota de colisão com os princípios de design do REST, por exemplo:

  • digamos que seu aplicativo esteja offline por um dia e você precise sincronizar com quatro tabelas dos bancos de dados back-end e precise de uma chamada como www.example.com/sync_everything?since=2015-07-24
  • digamos que haja uma tela em que o usuário possa editar muitos de seus objetos, por exemplo, marcando tarefas em sua lista de tarefas. deve haver uma maneira de editar todos esses registros de tarefas em uma única chamada de API em lote, em vez de uma chamada de API por edição.
  • digamos que exista uma tela que misture informações das tabelas db ORDER, SALESMEN e PRODUCT, eu deveria obter esses dados em uma chamada em vez de três.

o risco é que possamos acabar com a API mais tranquila que existe e também o aplicativo móvel que não responde de forma mais inútil.

O problema é que sou apenas um novo contratado e o que preciso é de algo que me ajude a argumentar, alguns artigos de fontes bem respeitadas ou algo assim. Principais players comprometendo-se com o estilo REST para seu cliente móvel (por exemplo: usando pontos finais de API agregados compostos).

Ou qualquer solução para esse problema geral. Obrigado!


3
Parece que sua pergunta pode ser: "Como uma API pode fornecer coleções de objetos e objetos incorporados de tipos semelhantes ou diferentes, mantendo o estilo REST?" Estou entendendo sua pergunta?
joshp

Acredito que a resposta geral é que cada chamada REST precisa ter uma variedade de parâmetros opcionais para que possa ser flexível e ainda relativamente intuitiva. O caso de sincronização sempre será complicado, mas, para páginas comuns, você normalmente vê várias chamadas do mesmo tipo , ou seja, todas as GETs, certo?
Ixrec 8/08/2015

1
Acho que adaptar sua API é a solução errada quando o problema é a falta de solicitações paralelas - 8 solicitações pequenas não são muito piores do que uma solicitação grande quando não precisam esperar uma pela outra. Você pode mudar para HTTP / 2? Ou pelo menos usar pipelining HTTP / 1.1?
Am

Consulte também: Padrões para manipular operações em lote nos serviços da web REST? . A chave é identificar quais tipos de comandos (e sob quais condições prévias) podem ser agrupados em lotes sem conflitos e, em seguida, criar uma representação JSON do pedido em lotes e enviá-los. Ele perde a principal atratividade do REST, que é o seu armazenamento em cache, mas o armazenamento em cache nem sempre é relevante para todos os tipos de aplicativos. Observe que o lote / simultaneidade não é aplicável se houver dependências lógicas.
Rwong 8/08

Uma analogia para a situação em que o intermediário precisa executar várias operações em uma sequência, com dependências lógicas não triviais em cada operação anterior, é algo como "procedimento armazenado", que é executado nesse intermediário em vez de dentro de um banco de dados. Abaixo, o intermediário tem permissão para converter uma única chamada de "procedimento armazenado" em quantas solicitações RESTful forem necessárias, mas esse é um detalhe de implementação do intermediário.
Rwong

Respostas:


27

A API que está sendo projetada segue o estilo Restante de operações URI e CRUD centradas em recursos mapeadas para verbos HTTP.

Este é o seu problema aqui.

Você limitou seus recursos a (suponho) os modelos em seu banco de dados. Como tal, está demorando muito tempo para carregar todos esses recursos, porque seu servidor não tem um conceito de recursos que não têm uma representação no banco de dados.

Por exemplo, pode ter

www.example.com/books/482094
www.example.com/books/582045
www.example.com/books/427454
www.example.com/books/319343

que tudo precisa ser carregado para obter minha biblioteca

Isso não é um problema com o design RESTful, é realmente um anti-padrão REST. Não há absolutamente nada no REST que diga que nossos recursos devem ter um mapeamento individual com qualquer outra coisa em seu sistema, incluindo modelos de banco de dados.

A solução é criar mais recursos que correspondam melhor ao que você deseja carregar. Se você tiver cinco recursos que sempre acabam juntos, crie um novo recurso que contenha as informações desses 5 recursos.

O que você deve ter é algo como isto

www.example.com/users/334/my_library

que apenas carrega todos os livros para esse usuário. "my_library" não é um modelo no seu banco de dados, mas é um recurso. O servidor o cria com base nos modelos no banco de dados, mas não há mapeamento 1 para 1 e o servidor tem flexibilidade para criar esse recurso sem alterar o modelo do seu banco de dados.

Você também pode ter

www.example.com/users/334/favioured_books
www.example.com/users/334/books_ordered_last_week
www.example.com/users/334/wishlist

nenhum deles precisa existir como modelo no banco de dados ou no espaço do domínio.

Existe um amplo conceito errôneo de que isso é algo errado, porque estruturas como o Rails ensinaram as pessoas a mapear recursos de uma a uma para modelos no espaço de domínio que mapeiam novamente de uma para uma com as linhas do banco de dados. Isso não é necessário nem recomendado.

Os recursos devem ser numerosos, baratos e leves . Deve ser fácil criá-los e eles devem ser abstraídos do seu modelo de domínio. Se você achar que precisa de um novo, basta fazer um novo. Se você tiver problemas para fazer isso, a falha de suas estruturas não é uma falha no REST.

Agora, a grande ressalva disso é se sua estrutura permite que você faça isso. Estruturas como Rails e Django, que seguiram o curso para mapear 1 para 1, a fim de "economizar seu tempo" tornam difícil fazer isso. Mas isso é uma falha nas estruturas, não no design RESTful.

Aqui está Jim Webber discutindo isso com mais detalhes (incluindo algumas escavações no Rails também!)

https://yow.eventer.com/yow-2011-1004/domain-driven-design-for-restful-systems-by-jim-webber-1047


Isso é muito interessante e eu concordo plenamente com isso, mas, infelizmente, não sou eu quem faz a API e tenho pouca maneira de influenciá-la, se houver. Muitas pessoas usam esse "antipadrão" todo (por muitas razões, as limitações da estrutura são uma) e apenas usam a definição de URI para pensar claramente sobre seu banco de dados. Os pontos de extremidade da API são apenas outra maneira de visualizar seu banco de dados ... Além disso, em alguns casos, criar um recurso como o que você descreveu é difícil devido ao fato de os objetos serem realmente diferentes, apenas nomeá-los levaria a termos muito vagos.
MikaelW

Para voltar ao problema do ponto de vista da eficiência, eles concordaram que, se uma tela móvel for muito lenta (e somente se isso aconteceu), haverá algumas chamadas compostas possíveis, mas elas estarão em um componente que envolve a API ( em vez da própria API), será usada apenas pelos clientes móveis e não será considerada como parte da API principal, o domínio principal.
MikaelW

@MikaelW, você está certo. Mesmo o que Cormac disse ser o cenário ideal, algumas vezes você trabalha com uma API que precisa atender a muitos outros sistemas (desktop, celular, web, trabalhos agendados, sistemas legados etc.). Esse tipo de API precisa ser realmente flexível, fornecendo recursos para atender a tantas possibilidades quanto possível, mas não pode atender a todas as necessidades específicas de desempenho de um consumidor. Nesse caso, você não tem muitas opções ...
Dherik
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.