Tuesday 24 April 2018

Estratégia de versionamento de aplicativos


Estratégia de versão de aplicativos
Eu tenho um aplicativo para iOS que usa o controle de versão semântico para marcar as compilações enviadas. Eu também estou usando o TestFlight da Apple para empurrar compilações internas para a equipe para testes / controle de qualidade.
Empurrar uma compilação interna requer o upload de uma compilação para o iTunes Connect. Não há distinção entre uma compilação de teste e uma compilação de lançamento para o iTunes Connect, e o iTunes Connect não permite sobrescrever versões carregadas anteriormente. Então toda vez que eu quero empurrar uma nova build para testes internos, eu tenho que aumentar o número da versão (bem, o número do patch (X. X.X)).
Isso funciona bem, exceto para os nossos usuários, parece que nossos números de versão saltam muito entre as atualizações. Por exemplo, se este é o nosso histórico de construção:
. então os usuários estão vendo apenas os lançamentos em negrito e nosso histórico de lançamentos parece estranho:
Eu pensei que uma boa maneira de evitar isso é usar versões beta, como v1.1.0-beta para as compilações de teste, mas o iTunes Connect rejeita qualquer seqüência de versão que não seja X. X.X.
Existe uma maneira de continuar usando o TestFlight para testes internos / controle de qualidade e evitar a aparência de um histórico de versão preenchido por falhas para os usuários?

Estratégia de versão de aplicativos
Esta é uma boa e uma pergunta complicada. O tópico de design de URI é ao mesmo tempo a parte mais proeminente de uma API REST e, portanto, um compromisso potencialmente de longo prazo com os usuários dessa API.
Como a evolução de um aplicativo e, em menor extensão, de sua API é um fato da vida e é até similar à evolução de um produto aparentemente complexo como uma linguagem de programação, o design de URI deve ter menos restrições naturais e deve ser preservado ao longo do tempo . Quanto maior o tempo de vida do aplicativo e da API, maior o comprometimento com os usuários do aplicativo e da API.
Por outro lado, outro fato da vida é que é difícil prever todos os recursos e seus aspectos que seriam consumidos por meio da API. Felizmente, não é necessário projetar a API inteira que será usada até o Apocalypse. É suficiente definir corretamente todos os endpoints de recursos e o esquema de endereçamento de cada recurso e instância de recurso.
Com o tempo, você pode precisar adicionar novos recursos e novos atributos a cada recurso específico, mas o método que os usuários da API seguem para acessar determinados recursos não deve ser alterado quando um esquema de endereçamento de recursos se tornar público e, portanto, final.
Este método se aplica à semântica do verbo HTTP (por exemplo, PUT deve sempre atualizar / substituir) e códigos de status HTTP que são suportados em versões anteriores da API (eles devem continuar a funcionar para que os clientes da API que trabalharam sem intervenção humana possam continuar trabalhando) Curtiu isso).
Além disso, como a incorporação da versão da API na URI interromperia o conceito de hipermídia como o mecanismo do estado do aplicativo (declarado na dissertação de doutorado de Roy T. Fieldings) por ter um endereço de recurso / URI que mudaria com o tempo, concluiria que a API As versões não devem ser mantidas em URIs de recursos por um longo tempo, o que significa que os URIs de recursos dos quais os usuários da API podem depender devem ser permalinks.
Claro, é possível incorporar a versão da API no URI de base, mas apenas para usos razoáveis ​​e restritos, como a depuração de um cliente de API que funciona com a nova versão da API. Essas APIs com versão devem ser limitadas no tempo e estar disponíveis apenas para grupos limitados de usuários da API (como durante betas fechados). Caso contrário, você se compromete onde não deveria.
Algumas considerações sobre a manutenção de versões da API com data de expiração. Todas as plataformas / linguagens de programação comumente usadas para implementar serviços da Web (Java,.NET, PHP, Perl, Rails, etc.) permitem uma vinculação fácil do (s) ponto (s) de extremidade do serviço da Web a um URI de base. Dessa forma, é fácil reunir e manter uma coleção de arquivos / classes / métodos separados em diferentes versões da API.
A partir do POV dos usuários da API, também é mais fácil trabalhar e vincular-se a uma determinada versão da API quando isso é óbvio, mas apenas por tempo limitado, ou seja, durante o desenvolvimento.
A partir do POV do desenvolvedor da API, é mais fácil manter diferentes versões da API em paralelo usando sistemas de controle de origem que trabalham predominantemente em arquivos como a menor unidade de versão (código-fonte).
No entanto, com as versões da API claramente visíveis no URI, há uma ressalva: também é possível objetar essa abordagem, já que o histórico da API se torna visível / aparente no design da URI e, portanto, está sujeito a mudanças ao longo do tempo que vai contra as diretrizes do REST. Concordo!
A maneira de contornar essa objeção razoável é implementar a versão mais recente da API sob URI de base da API sem versão. Nesse caso, os desenvolvedores de clientes da API podem optar por:
desenvolver contra o mais recente (comprometendo-se a manter o aplicativo protegendo-o de eventuais alterações de API que possam quebrar seu cliente de API mal projetado).
ligar a uma versão específica da API (que se torna aparente), mas apenas por um tempo limitado.
Por exemplo, se a API v3.0 for a versão mais recente da API, as duas seguintes devem ser aliases (ou seja, devem comportar-se de forma idêntica a todas as solicitações da API):
Além disso, os clientes da API que ainda tentam apontar para a API antiga devem ser informados para usar a versão da API anterior mais recente, se a versão da API que eles estiverem usando for obsoleta ou não for mais suportada. Então, acessando qualquer um dos URIs obsoletos como estes:
deve retornar um dos 30 códigos de status HTTP que indicam o redirecionamento usado em conjunto com o cabeçalho HTTP de local que redireciona para a versão apropriada do URI de recurso que permanece como esta:
Existem pelo menos dois códigos de status HTTP de redirecionamento que são apropriados para cenários de versão de API:
301 Movido permanentemente, indicando que o recurso com um URI solicitado é movido permanentemente para outro URI (que deve ser um permalink de instância de recurso que não contém informações sobre a versão da API). Esse código de status pode ser usado para indicar uma versão de API obsoleta / sem suporte, informando ao cliente de API que um URI de recurso com versão foi substituído por um link permanente de recurso.

Versão seu aplicativo.
Seu aplicativo deve ter versão de versão Definir a versão nos arquivos de criação Gradle do aplicativo Como sua versão afeta seus aplicativos como os usuários são atualizados Determine sua estratégia de versão no início do processo de desenvolvimento, incluindo considerações para versões futuras.
Neste documento.
O controle de versão é um componente essencial da atualização do seu aplicativo e da estratégia de manutenção. O controle de versão é importante porque:
Os usuários precisam ter informações específicas sobre a versão do aplicativo instalada em seus dispositivos e as versões de atualização disponíveis para instalação. Outras aplicações & mdash; incluindo outros aplicativos que você publica como um conjunto & mdash; precisa consultar o sistema para a versão do seu aplicativo, para determinar a compatibilidade e identificar dependências. Os serviços através dos quais você publicará seu (s) aplicativo (s) também podem precisar consultar seu aplicativo para sua versão, para que eles possam exibir a versão para os usuários. Um serviço de publicação também pode precisar verificar a versão do aplicativo para determinar a compatibilidade e estabelecer relacionamentos de atualização / downgrade.
O sistema Android usa as informações da versão do seu aplicativo para proteger contra downgrades. O sistema não usa informações de versão do aplicativo para impor restrições sobre atualizações ou compatibilidade de aplicativos de terceiros. Seu aplicativo deve impor restrições de versão e deve informar os usuários sobre elas.
O sistema Android não impõe a compatibilidade da versão do sistema conforme expresso pela configuração minSdkVersion nos arquivos de construção. Essa configuração permite que um aplicativo especifique a API mínima do sistema com a qual é compatível. Para obter mais informações, consulte Especificando a versão mínima da API do sistema.
Definir informações da versão do aplicativo.
Para definir as informações da versão do seu aplicativo, defina valores para as configurações de versão nos arquivos de criação do Gradle. Esses valores são então mesclados no arquivo de manifesto do aplicativo durante o processo de criação.
Observação: se o seu aplicativo definir a versão do aplicativo diretamente no & lt; manifest & gt; elemento, os valores de versão no arquivo de compilação Gradle substituirão as configurações no manifesto. Além disso, a definição dessas configurações nos arquivos de criação do Gradle permite que você especifique valores diferentes para diferentes versões do seu aplicativo. Para maior flexibilidade e para evitar possíveis substituições quando o manifesto é mesclado, você deve remover esses atributos da tag & lt; manifest & gt; elemento e defina suas configurações de versão nos arquivos de compilação do Gradle.
Duas configurações estão disponíveis e você deve sempre definir valores para ambas:
versionCode - Um inteiro usado como um número de versão interno. Esse número é usado apenas para determinar se uma versão é mais recente que outra, com números mais altos indicando versões mais recentes. Este não é o número da versão mostrado aos usuários; esse número é definido pela configuração versionName, abaixo. O sistema Android usa o valor de versionCode para proteger contra downgrades, impedindo que os usuários instalem um APK com um versionCode inferior à versão atualmente instalada em seu dispositivo.
O valor é um número inteiro para que outros aplicativos possam avaliar programaticamente, por exemplo, para verificar um relacionamento de upgrade ou downgrade. Você pode definir o valor para qualquer número inteiro desejado, mas deve garantir que cada versão sucessiva do seu aplicativo use um valor maior. Você não pode fazer upload de um APK para a Play Store com um versionCode que você já usou para uma versão anterior.
Observação: em algumas situações específicas, você pode querer enviar uma versão do seu aplicativo com um versionCode inferior à versão mais recente. Por exemplo, se você estiver publicando vários APKs, poderá ter intervalos de versionCode predefinidos para APKs específicos. Para mais informações sobre atribuição de valores de versionCode para vários APKs, consulte Suporte para vários APKs.
Normalmente, você lançaria a primeira versão do seu aplicativo com o versionCode definido como 1 e, em seguida, monotonicamente aumentaria o valor a cada lançamento, independentemente de o lançamento constituir um lançamento principal ou secundário. Isso significa que o valor de versionCode não tem necessariamente uma forte semelhança com a versão de lançamento do aplicativo que é visível para o usuário (consulte versionName, abaixo). Aplicativos e serviços de publicação não devem exibir esse valor de versão para os usuários.
Aviso: o maior valor que o Google Play permite para o versionCode é 2100000000.
O valor é uma string para que você possa descrever a versão do aplicativo como um & lt; major & gt;. & Lt; minor & lt; point & gt; string, ou como qualquer outro tipo de identificador de versão absoluta ou relativa. O versionName não tem outro propósito senão ser exibido aos usuários.
Você pode definir valores padrão para essas configurações incluindo-os no bloco defaultConfig <>, aninhado dentro do bloco android <> do arquivo build. gradle do seu módulo. Você pode substituir esses valores padrão para diferentes versões de seu aplicativo definindo valores separados para tipos de versão individuais ou tipos de produtos. O arquivo build. gradle a seguir mostra as configurações de versionCode e versionName no bloco defaultConfig <>, bem como o bloco productFlavors <>.
No bloco defaultConfig <> deste exemplo, o valor de versionCode indica que o APK atual contém a segunda versão do aplicativo, e a string versionName especifica que ele será exibido para os usuários como versão 1.1. Este arquivo build. gradle também define dois tipos de produtos, "demo" e "full". Como o sabor do produto "demo" define versionName como "1.1-demo", a compilação "demo" usa este versionName em vez do valor padrão. O bloco de sabor de produto "completo" não define versionName, portanto, ele usa o valor padrão de "1.1".
A estrutura do Android fornece uma API para permitir que você consulte o sistema em busca de informações sobre a versão do seu aplicativo. Para obter informações de versão, use o método getPackageInfo (java. lang. String, int) do PackageManager.
Nota: Quando você usa Instant Run, o Android Studio define automaticamente o versionCode como MAXINT e o versionName como "INSTANTRUN".
Especifique os requisitos de nível da API.
Se seu aplicativo exigir uma versão mínima específica da plataforma Android, você poderá especificar esse requisito de versão como configurações de nível de API no arquivo build. gradle do aplicativo. Durante o processo de criação, essas configurações são mescladas no arquivo de manifesto do seu aplicativo. Especificar requisitos de nível de API garante que seu aplicativo só possa ser instalado em dispositivos que estejam executando uma versão compatível da plataforma Android.
Nota: Se você especificar requisitos de nível de API diretamente no arquivo de manifesto do seu aplicativo, as configurações correspondentes nos arquivos de compilação substituirão as configurações no arquivo de manifesto. Além disso, a definição dessas configurações nos arquivos de criação do Gradle permite que você especifique valores diferentes para diferentes versões do seu aplicativo. Para maior flexibilidade e para evitar possíveis substituições quando o manifesto é mesclado, você deve remover esses atributos do link & lt; uses-sdk & gt; elemento e defina suas configurações de nível de API nos arquivos de construção do Gradle.
Existem duas configurações de nível de API disponíveis:
minSdkVersion & mdash; A versão mínima da plataforma Android na qual o aplicativo será executado, especificada pelo identificador de nível da API da plataforma. targetSdkVersion & mdash; Especifica o nível da API em que o aplicativo foi projetado para ser executado. Em alguns casos, isso permite que o aplicativo use elementos ou comportamentos de manifesto definidos no nível da API de destino, em vez de restringir-se a usar somente aqueles definidos para o nível mínimo da API.
Para especificar requisitos de nível de API padrão em um arquivo build. gradle, inclua uma ou mais das configurações acima no bloco defaultConfig <>, aninhado dentro do bloco android <>. Você também pode substituir esses valores padrão para diferentes versões de seu aplicativo, adicionando as configurações para criar tipos ou tipos de produtos. O seguinte arquivo build. gradle especifica as configurações padrão minSdkVersion e targetSdkVersion no bloco defaultConfig <> e substitui o minSdkVersion por um sabor do produto.
Ao se preparar para instalar seu aplicativo, o sistema verifica o valor dessas configurações e compara-as com a versão do sistema. Se o valor de minSdkVersion for maior que a versão do sistema, o sistema impedirá a instalação do aplicativo.
Se você não especificar essas configurações, o sistema presumirá que seu aplicativo é compatível com todas as versões da plataforma.
Para mais informações, consulte o & lt; uses-sdk & gt; documentação do elemento manifesto e o documento Níveis da API. Para configurações de compilação do Gradle, consulte Configurar variantes de compilação.

Seu versionamento de API está errado, e é por isso que decidi fazer isso de três formas diferentes e erradas.
No final, decidi que a maneira mais justa e equilibrada era irritar todo mundo igualmente. É claro que estou falando sobre versionamento de APIs e não desde as ótimas guias # x201C versus espaços & # x201D; debate tenho visto tantas crenças fortes em campos totalmente diferentes.
Isso foi ótimo. Quando eu construí Eu fui pwned? (HIBP) no final de novembro, foi concebido para ser um serviço simples e rápido que algumas pessoas usariam. Eu acho que é justo dizer que os dois primeiros pontos foram alcançados, mas não o último. Não era um "número um", na verdade, no final da primeira semana, era mais do que o Google Analytics poderia suportar. O ponto é que você não pode sempre prever o futuro quando você escreve sua API e em algum momento você pode precisar mudar algo que as pessoas já dependem.
Mas aqui está o problema & # x2013; toda vez que você começa a falar sobre qualquer coisa relacionada a APIs via HTTP, isso acontece:
Todo caminho que você vira, há diferentes filosoficos sobre o caminho certo & # x201D; e muito para trás e para frente no REST, o que é RESTful, o que não é e se é importante. Vamos falar sobre as alterações da API, o impacto sobre as versões, por que há tantas idéias divergentes sobre como isso deve ser feito e, por fim, por que nenhuma das brincadeiras é tão importante quanto realmente fazer as coisas.
Puxando mais dados de violação.
Tendo em mente que a mesma API é usada para o recurso de pesquisa no site e agora também por terceiros criando tudo, de aplicativos de smartphone a ferramentas de teste de penetração, a resposta acima funcionou bem no início, mas foi limitada. Por exemplo, esta resposta não funciona tão bem:
Por quê? Porque & # x201C; BattlefieldHeroes & # x201D; é o Pascal-cased que é ótimo para combiná-lo com classes CSS codificadas (embora provavelmente não seja uma boa abordagem de longo prazo) e por ter um & # x201C; stable & # x201D; nome para se referir a (eu não vou alterá-lo, mesmo que haja uma segunda violação), mas não é adequado para exibição como um título. Tudo isso sai do Armazenamento de Tabelas do Azure e eu entro no SQL Azure para extrair dados relacionais que realmente descrevem a violação. Um dos atributos nesse armazenamento relacional é o nome que você vê acima.
O que eu realmente queria fazer era algo mais assim:
Pegue? Para o ponto anterior sobre o nome da violação, que ainda está lá no atributo name, mas agora temos um título também. Isto é o que você mostra para as pessoas & # x2013; & # x201C; Battlefield Heroes & # x201D; & # x2013; mas mais importante, se o Gawker for penhorado novamente, posso nomear a violação de algo como Gawker2014 e o título pode ser algo amigável ao longo das linhas de Gawker (Ataque Eletrônico do Exército Sírio) & # x201D ;. Ele segmenta o que é estável e previsível daquilo que não é e significa que as pessoas podem criar dependências, como imagens ou outros recursos, no atributo name.
Os outros dados devem ser bem claros: a data da violação, quando foi adicionada ao sistema, o número de contas pwned, a descrição da violação (novamente, isso pode mudar se o palavreado precisar ser ajustado) e & # x201C; DataClasses & # x201D ;. Uma das coisas que muitas pessoas estavam pedindo era uma descrição do que estava comprometido na brecha, então agora há um monte de atributos que podem ser adicionados através de uma coleção sobre a violação em si. Eu já estou mostrando isso abaixo de cada violação na página de sites da Pwned (essa é outra razão pela qual eu posso agora ajustar algumas das descrições).
Esta é uma mudança urgente. Enquanto o sentimento da API é o mesmo & # x2013; forneça um nome de conta, receba de volta uma lista de violações & # x2013; não há mais uma matriz de strings de nomes de violações. Se eu simplesmente substituísse a API antiga por essa, as coisas iriam quebrar. APIs. Devo. Evoluir.
O software evolui, as APIs devem ser versionadas.
Vamos ser sinceros sobre isso: o mundo segue em frente. A API para o HIBP durou cerca de 2 meses, não porque foi mal projetada, mas porque o serviço se tornou insano e inesperadamente bem-sucedido. Eu gosto desse tipo de problema, e você também deveria.
Agora eu tive uma escolha; ou eu poderia me contentar com o que eu tinha e privar as pessoas de uma maneira melhor, eu poderia adicionar ao serviço existente de uma forma não violenta ou eu poderia criar uma nova versão (embora expondo a mesma entidade de uma maneira diferente) e construir É a melhor maneira de saber como; sem bytes desnecessários, modelados corretamente (até que eu decida que uma nova versão é mais correta) e uma boa representação da entidade que eu estou tentando finalmente entrar nos consumidores & # x2019; apps.
Não há nada de errado em introduzir uma nova versão de uma API quando é a coisa mais sensata a ser feita. Por todos os meios, faça o seu melhor para obtê-lo & # x201C; direita & # x201D; desde o primeiro dia, mas fazê-lo com a expectativa de que "certo" & # x201D; é um estado temporário. É por isso que precisamos estar aptos para a versão.
Os vários campos de versionamento.
Certo, então quão difícil pode ser esse negócio de versionamento? Quero dizer, deve ser um exercício simples, certo? O problema é que isso é muito filosófico, mas em vez de ficar atolado nisso por enquanto, deixe-me delinear as três escolas comuns de pensamento em termos de como elas são praticamente implementadas:
URL: basta digitar a versão da API no URL, por exemplo: haveibeenpwned / api / v2 / breachedaccount / foo Cabeçalho de solicitação personalizada: você usa o mesmo URL de antes, mas adiciona um cabeçalho como & # x201C; api-version: 2 & # x201D; Aceitar cabeçalho: você modifica o cabeçalho de aceitação para especificar a versão, por exemplo, & # x201C; Accept: application / vnd. haveibeenpwned. v2 + json & # x201D;
Tem havido muitas, muitas coisas escritas sobre isso e eu vou linkar para eles no final do post, mas aqui está a versão abreviada:
Os URLs são uma droga porque devem representar a entidade: na verdade, eu concordo com isso na medida em que a entidade que estou recuperando é uma conta violada, não uma versão da conta violada. Semanticamente, não é realmente correto, mas é fácil de usar! Cabeçalhos de solicitação personalizada são uma droga porque não é realmente uma forma semântica de descrever o recurso: A especificação HTTP nos dá um meio de solicitar a natureza que gostaríamos do recurso representado por meio do cabeçalho de aceitação, por que reproduzir? esta? Aceitar cabeçalhos chupados porque são mais difíceis de testar: não posso mais apenas fornecer a alguém um URL e dizer: "##201C; aqui, clique em" & # x201D ;, em vez disso, eles devem construir cuidadosamente a solicitação e configurar o cabeçalho de aceitação adequadamente .
Os vários argumentos a favor e contra cada abordagem tendem a ir de & # x201C; este é o & # x2018; certo & # x2019; maneira de fazer isso, mas é menos prático & # x201D; através de & # x201C; Esta é a maneira mais fácil de criar algo consumível que, portanto, faz com que seja "# & # x2018; right & # x2019; & # x201D ;. Há muita discussão sobre hipermídia, negociação de conteúdo, o que é & nbsp; REST & # x201D; e todo tipo de outras questões. Infelizmente, isso muitas vezes é filosófico e perde a visão de qual deve ser o objetivo real: construir um software que funcione e particularmente para uma API, tornando-a facilmente consumível.
É sobre ter um contrato estável, estúpido!
Mais importante do que todas as reclamações e delírios sobre como fazer isso dessa maneira ou daquela maneira é dar estabilidade às pessoas. Se eles investem seu esforço suado escrevendo código para consumir sua API, então é melhor que você não a interrompa mais adiante.
Honestamente, os debates sobre o que é o & # X201C; RESTful & # x201D; contra o que não é como se o próprio termo ditasse seu sucesso é apenas louco. Transforme essa discussão em "Aqui estão as razões práticas pelas quais isso faz sentido, e é isso que pode acontecer se você não o fizer", e eu farei de tudo. O problema é que até mesmo as vozes da razão dentro das discussões barulhentas deixam dúvidas quanto ao que realmente é a melhor abordagem e, portanto, eu alcancei um compromisso & # x2026;
Aqui estão 3 maneiras erradas de consumir a API de HIBP que você pode escolher agora.
Ok, agora que estamos claramente estabelecidos, mas você está errado, eu gostaria de dar a você a opção de escolher qualquer uma das três formas erradas. Espere & # x2013; o que?! É assim: no entanto, eu implemento a API, ela será muito difícil de consumir, muito acadêmica, muito provavelmente falha no proxy ou algo do tipo. Em vez de escolher um caminho errado, decidi dar-lhe todas as 3 formas erradas e pode escolher aquele que é o menos errado para você.
Caminho errado 2 - cabeçalho de solicitação personalizada:
Inevitavelmente, alguém vai me dizer que fornecer 3 formas erradas é a coisa errada a fazer. Não significaria mais código kludge para manter? Não, isso significa simplesmente que a implementação da API da Web subjacente é decorada com dois atributos:
O primeiro é simplesmente uma restrição de roteamento que implementa o RouteFactoryAttribute. Eu passo na rota e passo a versão que pode mapear para aquela rota, então a implementação procura a presença de um & # x201C; api-version & # x201D; cabeçalho ou um cabeçalho de aceitação correspondente a esse padrão:
Se a versão especificada em uma dessas combina com a especificada na restrição de roteamento, então, é o método que será invocado. Esta é uma adaptação simples desta amostra no CodePlex.
O segundo atributo que decora o método GetV2 acima é cortesia da Web API 2 e do recurso de roteamento de atributos. É claro que sempre poderíamos fazer roteamento na API da Web, mas isso geralmente era definido globalmente. O roteamento de atributos como esse traz a definição de rota para o contexto em que ela é aplicada e facilita a visualização da ação do controlador que será chamada por qual rota. Isso também significa que as implementações de todas as três formas erradas de chamar a API estão reunidas em um único local.
Então, em suma, não, isso não cria um monte de kludge e é muito fácil de manter. Cada uma das três abordagens retornará exatamente o mesmo resultado e, o mais importante, elas permanecerão estáveis ​​e não serão alteradas de forma alguma e, no final das contas, será a melhor opção. importante, independentemente de qual opção você escolher. Toda a implementação agora também está claramente documentada na página da API do site.
Mas e se você não especificar uma versão?
Você sabe o pouco onde eu disse que você não pode quebrar o que já está lá fora? Sim, isso significa que se você fizer o que faz agora, # x2013; não especifique uma versão & # x2013; então você começa o que você recebe agora. Em outras palavras, nenhum pedido para uma versão específica significa que você obtém a versão 1.
Estou bem com isso, independentemente de ter atingido este ponto por padrão. Eu sei que algumas pessoas sempre gostam de retornar a versão mais recente se um número não for especificado, mas IMHO que quebra todo o contrato estável & # x201; & # x201D; objetivo; o que você obtém da API hoje pode ser completamente diferente do que você recebe amanhã se eu revisá-lo. Isso seria uma droga e quebraria as coisas.
Você tem 3 opções, mas minha preferência pessoal é & # x2026;
Eu tenho o luxo de controlar tanto a API quanto o consumidor primário do site da HIBP. Dado que eu forneci 3 opções para consumir a API, qual delas eu mesmo uso?
Eu fui com o favorito filosófico que é especificá-lo através do cabeçalho de aceitação. Eu não acho que isso é certo e os outros estão errados, ao contrário, eu acho que isso faz mais sentido por duas razões principais:
Concordo que o URL não deve mudar: se concordarmos que o URL representa o recurso, a menos que estejamos tentando representar versões diferentes do próprio recurso, não, não acredito que o URL deva mudar. As brechas para foo são sempre as brechas para foo e eu não acho que só porque eu mudo os dados retornados para foo que a localização de foo deve mudar. Concordo que os cabeçalhos de aceitação descrevem como você deseja os dados: Esta é uma semântica da especificação de HTTP e assim como a semântica dos verbos de solicitação faz muito sentido (isto é, estamos obtendo ou colocando ou excluindo ou postando), O mesmo acontece com a maneira como o cliente gostaria que o conteúdo fosse representado.
De maneira nenhuma isso significa que eu acho que os outros dois estão errados e, francamente, não há melhor maneira de compartilhar a API com alguém do que dizer: "Aqui, clique aqui", mas quando eu puder facilmente construir o pedido e gerenciar os cabeçalhos, eu fui com esta rota.
Na verdade, pensando nisso, eu também uso a versão na rota do domínio. Por quê? Apenas através do processo de escrever esta API eu estava constantemente me comunicando com as pessoas sobre as formas de consultá-las (mais sobre isso mais tarde) e os atributos que ela retorna. Ser capaz de passar por um e-mail e dizer "Ei, aqui está o que eu estou pensando" ################################################################# e eles simplesmente clicam e obtêm resultados é inestimável. Esse é o ponto que os proponentes da abordagem de versionamento de URL fazem com razão: você simplesmente não pode fazer isso quando estiver dependente de cabeçalhos.
Ah, e no caso de você estar me checando, no momento em que escrevo, eu ainda não rolei o site para a v2 da API. Agora que os dados de violação são extraídos na API quando ocorre uma pesquisa, isso significa que eu tenho o luxo de não carregar todas as violações na origem na carga inicial (isso nunca será sustentável à medida que o conjunto de dados se expande). Isso salvará um monte de tráfego de saída e acelerará as coisas para as pessoas em termos de obter o site carregado, mas isso também significa um pouco mais de trabalho do meu jeito. Fique ligado.
No fechamento.
Claramente, eu tenho sido um pouco irônico aqui com relação a tudo estar errado, mas honestamente, quanto mais você lê sobre isso e quanto mais perguntas você faz, mais errado todo caminho parece de uma maneira ou de outra. Na verdade, eu sei muito bem que existem aspectos da minha implementação que serão referidos como "errados" e "x201D". (Eu posso pensar em pelo menos um par) e, naturalmente, eu estou me preparando para o potencial ataque de feedback para esse efeito. A coisa é, porém, cada uma dessas opções funciona e, francamente, para todos os efeitos práticos, eles funcionam tão bem quanto os outros.
Se eu puder deixar outras pessoas pensando em como atualizar suas APIs com um pensamento final: ninguém usará sua API até que você a tenha criado. Pare de procrastinar. Nenhuma dessas opções é "ruim", "# x201C; ruim & # x201D; em qualquer sentido tangível, eles são apenas diferentes. Eles são todos facilmente consumíveis, todos eles retornam o mesmo resultado e nenhum deles é susceptível de ter qualquer impacto real sobre o sucesso do seu projeto.
Referências.
Stack Overflow: Práticas recomendadas para o versionamento de API? (ótima pergunta, ótimas respostas, fechada como "não construtiva", eu assumo porque "Bill the Lizard & # x201D; saiu do lado errado da cama naquela manhã) Blog do Lexical Scope: How are REST APIs com versão? (boa comparação de práticas de controle de versão entre serviços, ainda que alguns anos atrás) CodePlex: Exemplo de restrição de roteamento (vinculado na página da API da Web da Microsoft como um exemplo de APIs de controle de versão adicionando um cabeçalho personalizado) CodeBetter: Versionamento RESTful Serviços (muito pragmáticos e uma boa descrição das várias maneiras pelas quais uma API pode mudar) Blog de Vinay Sahni: Práticas recomendadas para projetar uma API RESTful pragmática (ele está argumentando sobre o versionamento de URL por causa de & # x201C ; explorabilidade do navegador & # x201D;) Lans Pivotal: versionamento da API (boa visão das opiniões conflitantes existentes) Pilha Web de Amor: ASP. NET Web API Versioning com Tipos de Mídia (bom passo-a-passo de criar um aplicativo para suportar versionamento por negociação de conteúdo)
Oi, sou Troy Hunt, escrevo este blog, crio cursos para a Pluralsight e sou diretor regional da Microsoft e MVP que viaja pelo mundo falando em eventos e treinando profissionais de tecnologia.
Oi, sou Troy Hunt, escrevo este blog, crio cursos para a Pluralsight e sou diretor regional da Microsoft e MVP que viaja pelo mundo falando em eventos e treinando profissionais de tecnologia.
Próximos eventos.
Eu normalmente faço workshops particulares em torno destes, eis os próximos eventos públicos em que estarei:

Estratégia de versão de aplicativos
Esta questão já tem uma resposta aqui:
Eu estaria interessado em obter as opiniões da comunidade SO sobre a melhor estratégia de versionamento de aplicativos.
Como você acompanha o número da versão do seu aplicativo? Você tem uma definição formal do que cada número / personagem nessa versão representa?
O que os diferentes números / strings da versão do aplicativo significam para seu aplicativo?
Você usa algum sistema de atualização automatizado nos seus aplicativos (por exemplo, algo como o Sparkle) e quão bom ele está se comportando para você?
Você tem um procedimento de atualização separado para testadores beta ou testadores de pré-lançamento do seu aplicativo?
marcado como duplicado pelo mosquito, MichaelT, Kilian Foth, GlenH7, Rein Henrichs 29 de abril de 2013 em 2:42.
Esta pergunta foi feita antes e já tem uma resposta. Se essas respostas não responderem completamente à sua pergunta, faça uma nova pergunta.
migrated from stackoverflow May 18 '11 at 13:48.
This question came from our site for professional and enthusiast programmers.
How do you keep track of your application's version number? Do you have a formal definition of what each number/character in that version represents?
What do the different numbers/strings in the application's version mean for your app?
I use following:
Major - Major version is a definite release of the product. It increased when there are significant changes in functionality.
Minor - Minor version is incremented when only new features or major bug fixes have been added.
Upgrade/Patch - Upgrade refers to the replacement of a product with a newer version of product. It is incremented only when upgrade is provided on designated major release. Patch version starts with 0 and incremented only when bug has been resolved.
Build No - Build Number is incremented when new build is created.
Do you use any automated updating system in your apps (e. g. something like Sparkle) and how good has it been behaving for you?
We use building tool which automatically builds app at night which we call nightly build and this increases build number every time a build is created.
Do you have a separate update procedure for beta-testers or pre-release testers of your app?
No. Tester tests over nightly build at every morning which we call BAT(Build Acceptance Test) and verify nightly build.

No comments:

Post a Comment