Trabalhando com Change Streams do seu aplicativo Swift
Andrew Morgan4 min read • Published Jan 25, 2023 • Updated Jan 25, 2023
APLICATIVO COMPLETO
Avalie esse Início rápido
Meu trabalho diário é trabalhar com nossos maiores clientes para ajudá-los a tirar o melhor proveito do MongoDB ao criar novos aplicativos ou migrar os existentes. Seus casos de uso geralmente precisam de efeitos colaterais sempre que os dados são alterados — um dos requisitos mais comuns é manter uma trilha de auditoria.
Quando os clientes estão usando o MongoDB Atlas, é fácil indicar Atlas Triggers. Com triggers, você fornece o código, e o Atlas garante que ele seja executado sempre que os dados que você importa mudarem. Não há necessidade de levantar um servidor de aplicativos, e os triggers são muito eficientes, pois são executados junto com seus dados.
Infelizmente, ainda há algumas cargas de trabalho que os clientes não estão prontos para mover para a cloud pública. Para esses aplicativos, recomendamos change stream. Os change stream são o mecanismo subjacente usado pelo MongoDB Atlas Triggers e por muitas outras tecnologias do MongoDB — Kafka Connector, Charts, Spark Connector, Atlas Search, qualquer coisa que precise reagir a alterações de dados.
Usar change streams é surpreendentemente fácil. Solicite ao MongoDB Driver para abrir um fluxo de alteração e ele retornará um cursor do banco de dados. Ouça esse cursor e seu aplicativo receberá um evento para cada alteração em sua coleção.
Este post mostra como usar change streams de um aplicativo Swift. Os princípios são exatamente os mesmos para outros idiomas. Você pode encontrar muito mais sobre change streams no Developer Center.
Comece recentemente a usar o MongoDB Swift Driver pela primeira vez. Decidi criar um aplicativo de desktop Mac supersimples que permita navegar por suas coleções (o que o MongoDB Compass faz um trabalhomuito melhor) e exibir eventos de fluxo de alterações em tempo real (o que o Compass não faz atualmente).
Você pode baixar o código do repositório Swift-Change-Streams. Basta criar e executar a partir do Xcode .
Forneça sua connection string e navegue pelas suas collections. Selecione a opção " Ativar fluxos de alteração " para exibir eventos de alteração em tempo real.
Precisamos de uma variável para armazenar o fluxo de alterações (um cursor de banco de dados)
1 private var changeStream: ChangeStream<ChangeStreamEvent<BSONDocument>>?
bem como um para armazenar o evento de alteração mais recente recebido do fluxo de alterações (isso será usado para atualizar a interface do usuário):
1 private var latestChangeEvent: ChangeStreamEvent<BSONDocument>?
A função
registerChangeStream
é chamada sempre que o usuário marca ou desmarca a opção change stream:1 func registerChangeStream() async { 2 // If the view already has an active change stream, close it down 3 if let changeStream = changeStream { 4 _ = changeStream.kill() 5 self.changeStream = nil 6 } 7 if enabledChangeStreams { 8 do { 9 let changeStreamOptions = ChangeStreamOptions(fullDocument: .updateLookup) 10 changeStream = try await collection?.watch(options: changeStreamOptions) 11 _ = changeStream?.forEach({ changeEvent in 12 withAnimation { 13 latestChangeEvent = changeEvent 14 showingChangeEvent = true 15 Task { 16 await loadDocs() 17 } 18 } 19 }) 20 } catch { 21 errorMessage = "Failed to register change stream: \(error.localizedDescription)" 22 } 23 } 24 }
A função especifica quais dados deseja visualizar criando uma estrutura
ChangeStreamOptions
— você pode visualizar as opções disponíveis nos Docs do driver Swift. Neste aplicativo, especifico que deseja receber o novo documento completo (além dos deltas) quando um documento for atualizado. Observe que o documento completo é sempre incluído para operações de inserção e substituição.O código então chama
watch
na coleção atual. Observe que você também pode fornecer um pipeline de agregação como um parâmetro denominado pipeline
ao chamar watch
. Esse pipeline pode filtrar e remodelar os eventos que seu aplicativo recebe.Depois que a função de observação assíncrona for concluída, o loop
forEach
processará cada evento de alteração conforme ele é recebido.Quando o loop atualiza nossa variável
latestChangeEvent
, a alteração é automaticamente propagada para oChangeEventView
:1 ChangeEventView(event: latestChangeEvent)
Você pode ver todo o código para exibir o evento de alteração em
ChangeEventView.swift
. Mostrarei alguns destaques aqui.A visualização recebe o evento change da visualização envolvente (
CollectionView
):1 let event: ChangeStreamEvent<BSONDocument>
O código analisa o valor
operationType
no evento para determinar qual cor usar para a janela:1 var color: Color { 2 switch event.operationType { 3 case .insert: 4 return .green 5 case .update: 6 return .yellow 7 case .replace: 8 return .orange 9 case .delete: 10 return .red 11 default: 12 return .teal 13 } 14 }
documentKey
contém o valor_id
para o documento que foi alterado na coleção MongoDB:1 if let documentKey = event.documentKey { 2 ... 3 Text(documentKey.toPrettyJSONString()) 4 ... 5 } 6 }
Se a operação do banco de dados foi uma atualização, então o delta é armazenado em
updateDescription
:1 if let updateDescription = event.updateDescription { 2 ... 3 Text(updateDescription.updatedFields.toPrettyJSONString()) 4 ... 5 } 6 }
O documento completo após a aplicação da alteração no MongoDB é armazenado em
fullDocument
:1 if let fullDocument = event.fullDocument { 2 ... 3 Text(fullDocument.toPrettyJSONString()) 4 ... 5 } 6 }
Se o processamento dos eventos de alteração for um processo crítico, você precisará lidar com eventos como o travamento do processo.
O
_id.resumeToken
no ChangeStreamEvent
é um token que pode ser usado ao iniciar o processo para continuar de onde você parou. Basta fornecer esse token para as opçõesresumeAfter
ou startAfter
ao abrir o fluxo de alterações. Observe que isso pressupõe que os eventos que você perdeu não foram girados para fora do Oplog.Use Change Streams (ou Atlas Triggers, se você puder) para simplificar sua base de código desvinculando o tratamento de efeitos colaterais de cada local em seu código que altera dados.
Depois de ler esta publicação, você deve ter notado como é simples criar aplicativos que React às change stream usando o MongoDB Change Streams. Perguntas? comentários? Acesse nossa Comunidade de desenvolvedores para continuar a conversa!