Je n’ai jamais réussi à trouver un framework network qui soit simple d’utilisation autant pour des petits projets que pour de gros projets qui grossissent rapidement. Certains comme URLSession et Alamofire sont bas niveau et nécessitent toujours de mettre en place une architecture autour. D’autres comme Moya ont tenté des approches plus conviviales, mais ont du mal à s’organiser proprement dans de plus gros projets.
Avec l’arrivée des macros en Swift, des développeurs astucieux ont tenté des approches basées sur des protocols. Une vision tirant au maximum parti des macros, mais trop inflexible à mon sens.
Comment avoir le meilleur des deux mondes ? Un framework à la fois simple à prendre en main mais flexible pour les besoins les plus importants. C’est pour ces raisons que j’ai conçu NetworkKit.
- Une syntaxe simple, flexible et moderne.
- Une distinction entre requête et client.
- Middleware, interceptor, logger.
- Complètement personnalisable. Parfait pour les petits comme les gros projets.
Laissez-moi vous montrer la base de NetworkKit.
@Get("/users/:id/books")
struct GetBooks {
@Path
var id: String
@Query
let limit: Int
}
let request = GetBooks(id: "1234", limit: 10)
let client = Client("https://api.com")
let response: Response<[Book]> = try await client.perform(request)
let books = response.dataUne approche déclarative
NetworkKit utilise une approche déclarative pour les requêtes. C'est intuitif, lisible et on a un côté what you see is what you get. L’utilisation des macros m’a permis d’arriver à ce genre de résultat :
@Get("/users/:id/books")
struct GetUserBooks {
@Path
var id: String
@Query("s")
let search: String
}Cette syntaxe permet de construire rapidement des requêtes simples, tout en gardant une bonne lisibilité sur des requêtes plus complexes.
@Post("/users/:id/books")
struct PostUserBooks {
@Path
var id: String
@Body
struct Body {
let name: String
let author: Author
}
}Un exemple de requête POST avec un body.
Séparer client et requête
Il est très fréquent de travailler avec plusieurs environnements de dev (dev, staging, prod, etc.). Votre serveur change, mais vos requêtes restent les mêmes. C’est pourquoi NetworkKit sépare le client des requêtes. Il est ainsi possible d’envoyer la même requête à votre serveur de dev et de prod, sans avoir à déclarer deux fois la même chose.
@Get("/users/:id/books")
struct GetBooks {
@Path
let id: String
}
let request = GetBooks(id: "1234")
let dev = Client("https//localhost:3000")
let prod = Client("https://api.com")
let devResponse: Response<[Book]> = try await dev.perform(request)
let prodResponse: Response<[Book]> = try await prod.perform(request)Avec cette méthode, rien n'est déclaré en double.
De plus, sur des gros projets, on peut facilement arriver à des centaines de requêtes. Lorsque les projets grossissent, organiser les choses par fichier dans des dossiers est très efficace. Avec cette approche, vous pouvez utiliser le quick search d'Xcode pour rapidement accéder à vos requêtes.
Peut-il être adopté ?
Avec la version précédente de NetworkKit, j’espérais avoir quelques retours. Mais je n’en ai eu aucun. Et c'est tout à fait normal. Il est clair que pour qu’un dev choisisse votre framework plutôt qu’un autre plus populaire, celui-ci a intérêt à être vraiment solide. Avec le temps, j’ai pu prendre du recul sur l’utilisation que j’en faisais. Voici les points sur lesquels j’ai travaillé :
- Améliorer la syntaxe déclarative. J’espère que le côté simple mais complexe fera son effet.
- Un lifecycle pour les requêtes plus complet avec les middlewares et les intercepteurs.
- Renforcer l’existant : rendre ce qui existait déjà encore plus simple et permissif.
- Une bien meilleure documentation.
Je me sers de NetworkKit depuis ses débuts et de la nouvelle version depuis quelques temps dans mes projets personnels comme avec mes clients. Je suis convaincu que cette approche est fiable et elle s’est montrée capable de scale sur des gros projets.
Si vous êtes curieux et que vous souhaitez tester NetworkKit, vous pouvez trouver toutes les instructions d’installation sur le projet Github. N’hésitez pas à me faire des retours !