API de gravação - XML ​​quebrado (duas)

A primeira API MyStore apareceu há 10 anos. Todo esse tempo estamos trabalhando nas versões existentes da API e desenvolvendo novas. E várias versões da API já foram enterradas.

Este artigo terá várias coisas: como criar a API, por que o serviço em nuvem precisa, o que oferece aos usuários qual rake conseguimos e o que queremos fazer a seguir.

Meu nome é Oleg Alekseev oalexeev , sou diretor técnico e co-fundador da MySklad.

Por que criar uma API para um serviço


Nossos clientes, que são dezenas de milhares de empreendedores, estão usando ativamente soluções em nuvem: bancos, lojas on-line, contabilidade de produtos, CRM. Conectado a um - e já é difícil parar. E agora o quinto, oitavo, décimo serviço facilita o trabalho do empresário, mas os usuários transferem dados entre esses serviços em nuvem manualmente. O trabalho se transforma em um pesadelo.

A solução óbvia é oferecer aos usuários a capacidade de transferir dados entre serviços em nuvem. Por exemplo, importe e exporte dados como arquivos, que podem ser baixados no serviço desejado. Os arquivos geralmente são alterados para o formato de cada serviço. Esse é um trabalho manual mais ou menos simples, mas com o aumento do número desses serviços, fica mais difícil executá-lo.

Portanto, a próxima etapa é a API. Com ele, um serviço em nuvem se beneficia da conexão de vários serviços em um ponto. O surgimento de um ecossistema como esse atrai novos clientes devido a oportunidades adicionais. Um produto com nova funcionalidade se torna mais rentável e útil.

Se você criar suas próprias interfaces de programa, atrairá vendedores de terceiros na forma de programadores que conhecem seu produto graças à API. Eles começam a criar soluções baseadas na API proposta e ganham dinheiro automatizando as tarefas de seus clientes.

O sistema de contabilidade do MyStore é baseado em processos simples. O principal é trabalhar com documentos primários, a capacidade de aceitar e enviar mercadorias e receber relatórios comerciais com base no primário. Também há transferência de dados, por exemplo, para a contabilidade em nuvem e seu recebimento em sistemas bancários ou pontos de venda. Também trabalhamos com lojas on-line: recebemos informações sobre mercadorias e enviamos dados sobre saldos.

O ciclo de dados em torno das lojas online no MyStore

Primeira API MyStore


Ao longo de 10 anos de trabalho da MyStore com a API, adquirimos todos os tipos de integrações que permitem trocar dados, trabalhar com bancos, efetuar pagamentos e usar telefonia externa.

No primeiro ano, tornamos possível o upload de quaisquer dados no formato XML. Então, era muito mais compreensível e familiar os usuários manterem os dados offline, e não em algum tipo de nuvem, e nós lhes demos isso. O descarregamento foi iniciado pela exportação manual da interface. Ou seja, a API ainda não pôde ser chamada.

Então começamos a cooperar com a Rusagro - eles já usavam o ERP "adulto" para planejar a produção e as vendas, mas o carregamento de carros nas fábricas foi automatizado em MySklad. Portanto, recebemos os primeiros rudimentos dessa API: a troca entre nosso serviço e o ERP ocorreu enviando um arquivo grande com dados para todos os tipos de documentos.

Essa é uma boa opção para troca de dados em lote, mas junto com os documentos que eles tiveram para transferir suas dependências: informações sobre mercadorias, prestadores de serviços e armazéns. Um aterro desse tipo não é tão difícil de gerar durante a exportação, mas é bastante difícil desmontar durante a importação, pois todas as informações vêm em um único pacote: tanto sobre novos documentos quanto sobre os existentes.

A primeira API XML não durou muito - dois anos depois, começamos a reconstruí-la. Mesmo no início de seu trabalho, cometemos vários erros ao criar a interface do software.

Como a API XML foi criada: uma ilustração de um de nossos arquitetos. A propósito, aguarde seus artigos.
Como a API XML foi criada: uma ilustração de um de nossos arquitetos. A propósito, aguarde seus artigos.

Aqui estão nossos principais erros:

  1. A marcação JAXB foi feita diretamente nos beans de entidade. Usamos o Hibernate para nos comunicar com o banco de dados e a marcação JAXB foi feita nos mesmos beans. Esse erro ocorreu quase imediatamente: qualquer atualização na estrutura de dados levou à necessidade de notificar urgentemente todos os que usam a API ou criar muletas que garantissem compatibilidade com a estrutura de dados anterior.
  2. A API cresceu como uma espécie de adição e, inicialmente, não determinamos qual parte do produto compõe. Nem pensamos se a API era algo importante, se era necessário manter a compatibilidade com versões anteriores para seus primeiros clientes. Em algum momento, o número de usuários da API foi de cerca de 5% do número pequeno total, e nenhuma atenção foi dada a eles. A filtragem universal feita no devido tempo nos levou a ser usados ​​como back-end. Essa filtragem não era de todo o GraphQL, mas algo assim - funcionava com muitos parâmetros de string de consulta. Com uma ferramenta tão poderosa, era difícil para os usuários resistir e as solicitações foram transferidas para nós, para que fossem enviadas diretamente da interface do usuário de suas lojas online. A situação foi uma surpresa desagradável, porque a prestação de um serviço desse tipo deveria exigir cobrança diferente e um entendimento diferente da própria API como produto.
  3. Devido ao fato de a API não ter se desenvolvido como produto principal, a documentação da API foi produzida e publicada de acordo com o princípio residual - por meio da engenharia reversa. Dessa maneira, parece bastante simples e conveniente, mas contrário ao contrato de trabalho. É quando existe um determinado componente com um esquema de trabalho predefinido. O desenvolvedor o implementa de acordo com este esquema e tarefa, o componente é testado, o cliente recebe um produto que corresponde à ideia do analista. A engenharia reversa, por outro lado, lança um produto que simplesmente existe: com muletas, soluções estranhas e bicicletas, em vez da funcionalidade necessária.
  4. O fluxo inteiro de solicitações enviadas pela API não pôde ser analisado mais que um servidor de aplicativos ou log Nginx. Isso não nos permitiu isolar áreas de assunto, exceto talvez dividi-las por usuários e assinantes. Se não for possível regular o registro do aplicativo ou clientes, torna-se impossível analisar a situação. Esse problema teve o menor impacto no desenvolvimento da API; trata-se de entender sua relevância e funcionalidade.

Tentativa número dois: API REST


Em 2010, tentamos construir um sistema de câmbio com contabilidade online - BukhSoft. Não decolou. Mas, no processo de integração, apareceu uma API completa: um serviço de troca REST, no qual não havia liberdades como chamadas para operações na forma de chamadas RPC. Toda a comunicação com a API foi trazida para um modo padrão para descanso: a sequência de consultas contém o nome da entidade e a operação que é executada com ela é configurada usando o método http. Adicionamos filtragem no momento da atualização de entidades, e os usuários agora têm a oportunidade de criar replicação com seus sistemas.

No mesmo ano, apareceu uma API para descarregar os saldos de depósitos e mercadorias. As partes mais valiosas do sistema ficaram disponíveis para os usuários por meio da API - a troca de documentos primários e dados estimados sobre os saldos e o custo das mercadorias.

Em dezembro de 2015, o RetailCRM publicou a primeira biblioteca de terceiros para acessar nossa API. Eles começaram a usá-lo de maneira bastante ativa, enquanto a popularidade do serviço como um todo crescia, a carga na API crescia mais rapidamente que a carga na interface da web. Uma vez, o crescimento se transformou em um salto na carga.

Aqui a queda do Black Hawk. Ou o ancinho que passamos.

A solução é simples - dê a todos recursos iguais.

E esse salto, que é mostrado pela seta à esquerda, levou à total surpresa do servidor que atende à nossa API. Durante uma semana, entendemos o que exatamente essa carga gera. Acontece que essas são as mesmas solicitações transmitidas para nossa API pelas frentes dos clientes. Cerca de 50 clientes comeram tudo. Foi então que percebemos um de nossos erros - a completa ausência de limites.

Como resultado, introduzimos um limite no número de solicitações simultâneas. De uma conta, foi possível abrir simultaneamente não mais que dois pedidos. Isso é suficiente para trabalhar no modo de replicação para trocar dados no modo em lote. E aqueles que queriam nos usar como back-end, a partir desse momento, foram forçados a cumprir mais as tarifas, pois introduziram o trabalho em várias contas em seu software.

Arrumar


Desde 2014, a demanda pela API existente se tornou uma parte importante dos negócios, e a própria API gerou a maior quantidade de dados na troca de dados com os clientes. Em 2015, lançamos um projeto para limpar a API. Escolhemos JSON em vez de XML como formato e começamos a construí-lo com base nos recursos que foram revelados durante a implementação da versão anterior:

  1. Capacidade de gerenciar versões. O controle de versão permite desenvolver uma nova versão sem afetar um aplicativo existente e sem interromper os usuários.
  2. A capacidade do usuário ver metadados na resposta que ele recebe.
  3. A capacidade de trocar documentos grandes. Se processarmos um documento com um número de posições superior a 4-5 mil, isso se tornará um problema para o servidor: uma transação longa, uma solicitação http longa. Criamos um mecanismo especial que permite atualizar o documento em partes e gerenciar posições individuais deste documento enviando-as para o servidor.
  4. Ferramentas para replicação - estavam na versão anterior.
  5. Os limites de carga são como o legado do rake que foi pisado na versão anterior. Introduziu limites no número de solicitações em um período de tempo, no número de solicitações simultâneas e solicitações de um endereço IP.

A partir desse momento, lançamos duas versões menores da API e lançamos várias APIs especializadas, mas, em geral, a abordagem permaneceu inalterada. Um formato de troca atualizado e uma nova arquitetura tornaram possível corrigir deficiências na API muito mais rapidamente.

API MyStore hoje


Hoje, a API do MyStore resolve muitos problemas:

  • troca de dados com lojas on-line, sistemas de contabilidade, bancos;
  • receber dados de liquidação, relatórios;
  • usar como back-end para aplicativos clientes - nossos aplicativos móveis e caixa eletrônico de mesa funcionam através da API
  • envio de notificações sobre alterações de dados no MyStore - webhooks;
  • telefonia;
  • sistemas de fidelidade.

Com base na API, nosso CEO Askar Rakhimberdiev rhino, em quatro horas, escreveu um bot de telegrama que puxa o resto através da API: github.com/arahimberdiev/com-lognex-telegram-moysklad-stock

Agora números secos.

Aqui estão nossas estatísticas para a antiga API REST:

  • 400 empresas;
  • 600 usuários;
  • 2 milhões de solicitações por dia;
  • 200 Gb / dia de tráfego de saída.

E aqui está o que descobrimos com toda a API MyStore:

  • mais de 70 integrações (algumas delas podem ser encontradas aqui www.moysklad.ru/integratsii );
  • 8500 empresas;
  • 12.000 usuários;
  • 46 milhões de solicitações por dia;
  • 2 TB / dia de tráfego de saída.

O que vem a seguir


Os planos de desenvolvimento da API estão em discussão ativa. Tentamos levar em conta a experiência operacional que os usuários nos fornecem. Nem sempre e nem tudo acaba por ser feito imediatamente, mas não muito longe, é uma nova versão da API com metadados mais convenientes e uma estrutura menos pesada, OAuth para autenticação, uma API para aplicativos incorporados à interface.

Você pode acompanhar as notícias em um site especial para desenvolvedores de integração com o MySklad: dev.moysklad.ru .

Source: https://habr.com/ru/post/pt453136/


All Articles