A dependência de fornecedor (lock-in) raramente chega como uma única decisão. Ela se acumula aos poucos, um atalho conveniente de cada vez, até que uma base de código que começou como uma integração razoável com um provedor tenha se tornado, sem alarde, difícil de separar desse provedor. Vale a pena reconhecer alguns padrões específicos como sinais de alerta, porque cada um deles, isoladamente, parece inofensivo quando acontece.
Os nomes exatos dos campos de um provedor são usados em todo o seu próprio modelo de dados. Se o esquema do seu banco de dados, as respostas da sua API interna e o seu código de front-end usam a nomenclatura de campos de um provedor específico, formatted_address ou display_name ou como quer que esse provedor chame o campo, em vez de uma nomenclatura escolhida por você e traduzida uma única vez na fronteira, cada camada da sua aplicação absorveu uma dependência das convenções desse único fornecedor.
As peculiaridades específicas de um provedor foram contornadas na lógica de negócio, e não isoladas na fronteira da integração. Se uma solução alternativa para uma peculiaridade específica na forma como um provedor formata um endereço atípico fica dentro da lógica de negócio geral, e não dentro da função restrita que conversa com esse provedor, migrar significa caçar e desembaraçar essa solução alternativa de um código que, à primeira vista, não tem nada a ver com geocodificação.
Ninguém consegue responder rapidamente quantos lugares da base de código mencionam o provedor pelo nome. Se responder "onde dependemos desse fornecedor" exige uma auditoria cuidadosa em vez de uma resposta rápida e segura, essa incerteza já é um sinal de dependência, pois significa que ela se espalhou além do que qualquer pessoa vinha acompanhando ativamente.
Os tipos de objeto específicos da biblioteca cliente são usados como assinaturas de funções em outras partes do código. Se funções sem relação com geocodificação aceitam como parâmetro o tipo de resposta do SDK de um provedor específico, o sistema de tipos desse provedor passou, na prática, a fazer parte do sistema de tipos da sua própria aplicação, e removê-lo exige mexer em cada função que o referencia, não só no código de geocodificação.
Uma migração nunca foi testada, nem parcialmente, nos anos em que a integração está no ar. Uma integração que teoricamente poderia migrar para outro provedor, mas que nunca foi de fato testada com outro, não é, na prática, muito diferente de uma que não pode migrar de jeito nenhum, até que alguém realmente a teste.
Nenhum desses padrões é catastrófico por si só, e a maioria das integrações apresenta pelo menos um deles sem consequências reais por muito tempo. O valor de reconhecê-los está em poder transformar a dependência em uma troca deliberada e aceitável, em vez de uma acidental que ninguém escolheu. Às vezes a conveniência compensa o acoplamento, especialmente em um projeto pequeno em que uma migração completa custaria mais tempo de engenharia do que a flexibilidade vale. O problema só existe quando a dependência acontece de forma invisível e é descoberta no pior momento possível, durante uma migração forçada com prazo, em vez de ser reconhecida e aceita de propósito com antecedência.
Se já existe um host de compatibilidade para o provedor do qual você depende hoje, parte desse risco é naturalmente menor, já que os 17 hosts de compatibilidade significam que pelo menos um caminho de migração provável não exige desembaraçar nenhuma dependência no nível dos campos, apenas trocar o host e a chave. É um seguro razoável para ter mesmo em uma integração que você não tem nenhum plano imediato de migrar.