Modularización de apps iOS con Apollo y SPM

Compartir esta publicación

En el panorama del desarrollo moderno, GraphQL ha revolucionado nuestra forma de pensar sobre las API y la recuperación de datos. Cuando se trata de desarrollo iOS, integrar GraphQL puede ser pan comido, gracias a librerías como Apollo. Pero, ¿cómo dar un paso más y hacer que tu implementación sea modular utilizando Swift Package Manager (SPM)? Este artículo te guiará a través de los beneficios, inconvenientes y el proceso paso a paso para lograr este enfoque modular.

¿Por qué Apolo?

Apollo se ha convertido en uno de los clientes GraphQL más populares gracias a su robusto conjunto de características, incluyendo caché inteligente, actualizaciones en tiempo real y un sólido sistema de tipos. Pero una de sus ventajas menos comentadas es su compatibilidad con Swift y el soporte nativo para la modularización a través de SPM.

Necesidad de modularización

A medida que las aplicaciones crecen, mantener un código limpio y reutilizable se convierte en todo un reto. La modularización, o el proceso de dividir un programa en subprogramas separados, es una estrategia para gestionar esta complejidad. Mediante la creación de un módulo separado para el cliente Apollo GraphQL, podemos:

  • Mantenga el código relacionado con GraphQL aislado de otras partes de la aplicación.
  • Reutilice el módulo en varios proyectos.
  • Facilitar la gestión y comprensión del código base.

Cómo implementar un cliente GraphQL Apollo modular.

Paso 1: Inicializar un nuevo paquete Swift

En el directorio de tu proyecto, ejecuta:

swift package init --type library GraphQLClient

Este comando inicializa un nuevo paquete Swift llamado GraphQLClient.

Paso 2: Configuración del paquete Swift

Ahora, vamos a crear un Package.swift robusto que defina nuestro módulo junto con un objetivo de pruebas separado y un plugin para el Apollo CLI.

// swift-tools-version: 5.7
import PackageDescription

let package = Package(
    name: "GraphQLClient",
    platforms: [
        .iOS(.v14),
        .macOS(.v10_14)
    ],
    products: [
        .library(
            name: "GraphQLClient",
            targets: ["GraphQLClient"]),
        .library(name: "GraphQLClientTesting",
                 targets: ["GraphQLClientTesting"]),
        .plugin(name: "GenerateApolloCli",
                targets: ["GenerateApolloCli"])
    ],
    dependencies: [
        .package(url: "https://github.com/apollographql/apollo-ios.git",
                 from: "1.3.3")
    ],
    targets: [
        .target(
            name: "GraphQLClient",
            dependencies: [.product(name: "Apollo", package: "apollo-ios")],
            path: "./Sources",
            exclude: ["Tests"],
            swiftSettings: [
                .unsafeFlags(["-suppress-warnings"])
            ]),
        .target(name: "GraphQLClientTesting",
                dependencies: [.product(name: "ApolloTestSupport", package: "apollo-ios")],
                path: "./Sources/Tests"),
        .plugin(
            name: "GenerateApolloCli",
            capability: .command(
                intent: .custom(
                    verb: "apollo-cli-generate", // Verb used from the command line
                    description: "Generates graphql"),
                permissions: [
                    .writeToPackageDirectory(reason: "Generate code for graphql")
                ]),
            dependencies: [
                .product(name: "apollo-ios-cli", package: "apollo-ios")
            ],
            path: "Plugins/GenerateApolloCli"
        )
    ]
)

Dentro de esta configuración, estamos definiendo tres componentes significativos:

  De ViewModel a Compose Presenter

1. GraphQL Client: GraphQLClient

Esto sirve como nuestro cliente Apollo, el motor central a través del cual enviaremos consultas y mutaciones GraphQL. Al modularizarlo, garantizamos una separación clara de la lógica de nuestra aplicación, lo que permite actualizaciones sencillas y una posible reutilización en distintos proyectos.

Este objetivo incluye dependencias para Apollo y establece la ruta y las exclusiones para nuestros archivos fuente, asegurando una navegación limpia y advertencias de compilación mínimas.

2. Testing Module: GraphQLClientTesting

Con el objetivo de conseguir unas prácticas de pruebas sólidas, separamos nuestras preocupaciones de pruebas estableciendo un módulo de pruebas dedicado.

Esto permite el uso de respuestas simuladas, creando un entorno controlado para nuestras pruebas de integración y garantizando que la lógica de nuestra aplicación maneja los datos correctamente, sin realizar llamadas reales a la API.

3. Plugin de generación de código: GenerateApolloCli

La generación de código es una característica fundamental en el desarrollo de GraphQL, ya que automatiza la creación de estructuras y tipos de consulta. Con la generación de código de Apollo CLI y nuestro plugin personalizado para Xcode, mejoramos nuestro flujo de trabajo de desarrollo.

Este complemento permite a los desarrolladores ejecutar la generación de código Apollo CLI directamente desde Xcode, lo que simplifica el proceso y mejora la productividad al reducir el cambio de contexto entre el terminal y el IDE.

Paso 3: Configuración de Apollo Codegen

Cuando se trabaja con Apollo en Swift, el archivo apollo-codegen-config.json juega un papel fundamental en la dirección de la generación de código. Configura las operaciones de la CLI de Apollo cuando genera tipos y operaciones para tus consultas GraphQL. Analicemos un ejemplo de configuración:

{
    "schemaNamespace" : "MyNamespaceGraphql",
    "input" : {
        "operationSearchPaths" : ["**/*.graphql"],
        "schemaSearchPaths" : ["**/*.graphqls"]
    },
    "output" : {
        "testMocks" : {
            "absolute" : {
                "path": "./Sources/Tests/Mocks",
                "accessModifier": "public"
            }
        },
        "schemaTypes" : {
            "path" : "./Sources/GraphQLClient/Generated",
            "moduleType" : {
                "embeddedInTarget": {
                    "name": "GraphQLClient",
                    "accessModifier": "public"
                }
            }
        },
        "operations" : {
            "inSchemaModule" : {}
        }
    }
}

1. Espacio de nombres del esquema:

"schemaNamespace" : "MyNamespaceGraphql"

Esto define el espacio de nombres para los tipos de esquema generados, asegurando que tus tipos GraphQL estén encapsulados bajo un espacio de nombres dedicado,MyNamespaceGraphql, previniendo conflictos de nombres y asegurando una integración limpia dentro de tu código Swift.

2. Configuración de entrada:

"input" : {
    "operationSearchPaths" : ["**/*.graphql"],
    "schemaSearchPaths" : ["**/*.graphqls"]
}

La sección de input dicta dónde debe buscar Apollo los archivos .graphql y .graphqls dentro de tu proyecto, permitiéndote organizar tus documentos GraphQL de forma flexible sin restringirlos a un único directorio.

3. Configuración de salida:

La sección de output es más granular, controlando los destinos y los niveles de acceso del código generado y los mocks.

  • Mocks de prueba: Test Mocks: "testMocks" : { "absolute" : { "path": "./Sources/Tests/Mocks", "accessModifier": "public" } } Esta subsección asegura que tus mocks de prueba generados (respuestas de datos simuladas para tus operaciones) residen en ./Sources/Tests/Mocks y son accesibles públicamente, facilitando la simplificación de las pruebas.
  • Tipos de esquema: "schemaTypes" : { "path" : "./Sources/GraphQLClient/Generated", "moduleType" : { "embeddedInTarget": { "name": "GraphQLClient", "accessModifier": "public" } } }. Aquí, guiamos al Apollo CLI para que coloque los tipos de esquema generados en ./Sources/GraphQLClient/Generated. Además, al incrustarlos en el objetivo GraphQLClient con acceso público, estos tipos se pueden utilizar fácilmente dentro de tu módulo cliente GraphQL.
  • Operaciones: json "operations" : { "inSchemaModule" : {} } Al dejar inSchemaModule vacío, estamos indicando a Apollo que genere los tipos de operaciones (tipos de consulta, mutación y gestión de suscripciones) en el mismo módulo que los tipos de esquema, asegurando la cohesión y la facilidad de acceso en tu código Swift.
  Studio Bot: una IA para Android Studio
CTA Software

Paso 4: Incorporación del lenguaje de definición de esquemas (SDL) para la generación de código

La esencia de la interacción con una API GraphQL gira en torno a la comprensión del esquema de la API: sus tipos, consultas, mutaciones y suscripciones. El Lenguaje de Definición de Esquemas (SDL) es fundamental en este sentido, ya que proporciona una definición estructural y de tipos de la API que Apollo utiliza para generar el código Swift correspondiente.

¿Por qué es crucial SDL?

La SDL proporciona un plano de la API GraphQL, describiendo todas las posibles consultas, mutaciones y estructuras de datos de su API. Sin ella, la herramienta codegen de Apollo carecería del contexto necesario para generar tipos y operaciones que se alineen con la API.

Integración de SDL en el proyecto

Para involucrar SDL en la generación de código, asegúrese de que el archivo .graphqls que contiene el SDL de su API GraphQL se coloca en la ruta especificada en su apollo-codegen-config.json.

Paso 5: Definición de consultas y mutaciones con archivos .graphql

Elaborar y gestionar tus consultas y mutaciones es un paso esencial para dar forma a tus interacciones GraphQL y, en consecuencia, al código generado a través de Apollo. El uso de archivos .graphql te permite articular las operaciones exactas que realizará tu aplicación, lo que garantiza que Apollo genere únicamente el código necesario.

Formulación de archivos .graphql:

1. Definir con precisión: Cada archivo .graphql debe encapsular una única consulta, mutación o suscripción. Esto garantiza la claridad y facilita el seguimiento de los cambios en sistemas de control de versiones como git.

2. Organízalos estratégicamente: Almacena los archivos .graphql en una estructura de directorios lógica y jerárquica que refleje su uso dentro de su aplicación. Por ejemplo, agrupando todas las operaciones relacionadas con el usuario en un directorio /user

# Example Query in a .graphql File
query GetUser($userID: ID!) {
    user(id: $userID) {
        id
        name
        email
    }
}

Generación de código a medida:

Especificando las operaciones exactas que utilizará tu aplicación, Apollo CLI generará código Swift que lo sea:

  • Minimizado: Sólo se generan los tipos y operaciones necesarios.
  • Optimizada: Garantiza que su aplicación no esté sobrecargada de código y tipos no utilizados, agilizando su binario y minimizando los posibles puntos de fallo.
  Fase de descubrimiento de un proyecto de desarrollo de software

Asegúrate de que tus archivos .graphql están almacenados en el directorio especificado en tu apollo-codegen-config.json, permitiendo a Apollo CLI localizarlos y utilizarlos durante la generación de código.

"input" : {
    "operationSearchPaths" : ["**/*.graphql"]
}

Con sus consultas y mutaciones estratégicamente definidas y organizadas, no solo agiliza la generación de código, sino que también mejora la claridad y la capacidad de mantenimiento de sus operaciones. El código sencillo y adaptado generado por Apollo garantiza que su aplicación se mantenga optimizada y robusta, independientemente de la complejidad de su API GraphQL.


Sus pasos, desde la incorporación de SDL hasta la definición de consultas y mutaciones, proporcionan un enfoque fluido y eficiente para aprovechar GraphQL con Apollo en Swift, garantizando que su desarrollo no solo sea sólido y seguro desde el punto de vista tipográfico, sino también una experiencia placentera y coherente.

Ventajas de la modularización

  1. Reutilización: El módulo Apollo Client puede utilizarse en varios proyectos, lo que ahorra tiempo de desarrollo.
  2. Mantenibilidad: Aislar el código GraphQL facilita su gestión y actualización.
  3. Separación de intereses: Mantiene el código base de la aplicación principal limpio y centrado.

Inconvenientes de la modularización

  1. Sobrecarga inicial: El proceso de configuración puede parecer excesivo para proyectos pequeños.
  2. Gestión de dependencias: La gestión de las dependencias de los paquetes puede resultar compleja.
  3. Versionado: Mantener el módulo sincronizado con el proyecto principal requiere una estrategia de versionado.

Conclusión

La implementación de un cliente Apollo GraphQL modular a través del gestor de paquetes Swift no sólo hace que su código base sea más limpio, sino que también mejora la reutilización y la capacidad de mantenimiento. Aunque puede haber cierta sobrecarga de configuración inicial y complejidades adicionales en la gestión de dependencias, los beneficios a largo plazo a menudo superan estos inconvenientes. Aprovechando tanto Apollo como SPM, puedes crear aplicaciones iOS robustas, modulares y eficientes.

Referencias

Para más información y directrices detalladas sobre Apollo GraphQL y Swift Package Manager, puedes visitar los siguientes recursos:

  1. Documentación de Apollo GraphQL para iOS:
  1. Documentación del gestor de paquetes Swift:

Siéntase libre de profundizar en estos documentos para mejorar su comprensión y solucionar cualquier problema que encuentre durante su viaje de desarrollo.

Author

  • Aitor Pagan 1

    Aitor is an enthusiastic iOS Engineer eager to contribute to team success through hard work, attention to detail and excellent organizational skills. Clear understanding of iOS Platforms and Clean Code Principles and training in Team Management. Motivated to learn, grow and excel in Software Engineering.

    Ver todas las entradas

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Suscríbete a nuestro boletín de noticias

Recibe actualizaciones de los últimos descubrimientos tecnológicos

¿Tienes un proyecto desafiante?

Podemos trabajar juntos

apiumhub software development projects barcelona
Secured By miniOrange