Philip Withnall
philip.withnall@collabora.co.uk 2015
Compatibilidade reversa nas APIs
Rafael Fontenelle
rafaelff@gnome.org 2017

# Estabilidade de API

#

        Resumo

          Defina garantias de estabilidade de API para seu projeto. ()
          Certifique-se de que números de versão sejam alterados conforme apropriado quando a API é alterada. ()

# API e ABI

Em um nível alto, uma API – Application Programming Interface ou interface de programação de aplicação – é o limite entre dois componentes quando se está desenvolvendo para eles. Ela está intimamente relacionada a uma ABI – Application Binary Interface ou interface binária de aplicação – que é o limite em tempo real. Ela define as formas possíveis nas quais outros componentes podem interagir com um componente. Mais concretamente, ela normalmente significa que os cabeçalhos C de uma biblioteca formam sua API, e biblioteca compilada simboliza sua ABI. A diferença entre uma API e uma ABI é dada pela compilação do código: há certas coisas em um cabeçalho C, tal como `#define`s, que podem fazer com que uma API da biblioteca seja alterada sem alterar sua ABI. Mas essas diferenças são em sua maioria acadêmicas e, para todos os propósitos práticos, API e ABI podem ser tratados de forma intercambiável.

Exemplos de alterações incompatíveis com API para uma função C seria adicionar um novo parâmetro, alterar o tipo de retorno da função ou remover um parâmetro.

Porém, muitas outras partes de um projeto podem formar uma API. Se um daemon se expõe no D-Bus, as interfaces exportadas lá formam uma API. Similarmente, se uma API C é exposta em linguagens de alto nível pelo uso de GIR, o arquivo GIR forma uma outra API — se ela é alterada, qualquer código de alto nível usando-a também é alterado.

Outros exemplos de APIs mais incomuns são locais e formatos de arquivos de configuração, e esquemas de GSettings. Quaisquer alterações nestes poderia exigir que o código usando sua biblioteca seja alterado.

# Estabilidade

Estabilidade da API se refere a algum nível de garantia de um projeto que sua API será alterada apenas em formas definidas no futuro, ou jamais será alterada. Geralmente, um API é considerada ‘estável’ se ela se compromete em manter compatibilidade com versões anteriores (definido abaixo); mas APIs pode também se comprometer em ser instáveis ou até mesmo compatíveis com versões posteriores. O propósito das garantias de estabilidade de API é permitir que as pessoas usem seu projeto para seus próprios código se preocupar em atualizar constantemente seu código para se manter em dia com as alterações da API. Garantias comuns de estabilidade de API significa que o código que é compilado com uma versão de uma biblioteca vai funcionar sem problemas contra todas versões futuras daquela biblioteca com o mesmo número de versão maior — ou similarmente àquele código que funciona com um daemon vai continuar a funcionar em todas as versões futuras daquele daemon com o mesmo número de versão maior.

É possível aplicar diferentes níveis de estabilidade de API a componentes dentro de um projeto. Por exemplo, as funções centrais em uma biblioteca poderiam ser estáveis e, consequentemente, sua API mantida inalterada no futuro; enquanto as funções mais novas e menos centrais serem mantidas instáveis e poderem ser alteradas descontroladamente até que o design certo seja encontrado, ponto no qual elas poderiam ser marcadas como estáveis.

Vários tipos de estabilidade comumente considerados:

## Instável (unstable)

A API poderia alterar ou ser removida no futuro.

## Compatibilidade com versões anteriores

Apenas alterações que permitem código compilado com a API não modificada para continuar funcionando com a API modificada são permitidos (por exemplo, funções não podem ser removidas).

## Compatibilidade com versões posteriores

Apenas alterações que permitem código compilado com a API modificada para funcionar com a API modificada são permitidos (por exemplo, funções não podem ser adicionadas).

## Totalmente estável

Nenhuma alteração é permitida à API, apenas para a implementação.

Geralmente, projetos se comprometem com compatibilidade reversa quando eles dizem que uma API é ‘estável’. Muito poucos projetos se comprometem à total estabilidade por impediria quase que todos os desenvolvimentos posteriores do projeto.

# Versionamento

Garantias de estabilidade de API estão fortemente vinculadas a versionamento do projeto; tanto versionamento de pacote e versionamento do libtool. Versionamento do libtool existe totalmente para o propósito de rastrear a estabilidade da ABI e é explicado em detalhes em Autotools Mythbuster (Caçador de mitos de autotools) ou .

Versionamento de pacote (maior.menor.micro) está fortemente vinculado à estabilidade da API: geralmente, o número da versão maior é incrementado quando alterações incompatíveis com versões anteriores são feitas (por exemplo, quando funções são renomeadas, parâmetros são alterados, ou funções são removidas). O número da versão menor é incrementada quando alterações incompatíveis com versões posteriores são feitas (por exemplo, quando uma nova API pública é adicionada). O número da versão micro é incrementada quando as alterações no código são feitas sem modificar a API. Veja para mais informações.

Versionamento de API é tão importante para APIs de D-Bus e esquemas de GSettings (se eles são suscetíveis de alterações) quanto é para APIs C. Veja a documentação sobre versionamento de API de D-Bus para detalhes.

Para APIs GIR, sua estabilidade geralmente segue a estabilidade da API C, como elas são geradas a partir da API C. Uma complexidade é que sua estabilidade depende adicionalmente na versão do gobject-introspection usada na geração do GIR, mas versões recentes não foram muito alteradas, de forma que isso não é uma grande preocupação.

# Links externos

O tópico de estabilidade de API é coberto nos seguintes artigos (em inglês):

Wikipedia page on APIs

Wikipedia page on ABIs

Documentação de versionamento de API D-Bus