7 ms·
Exciting stuff. With async/await landing last week and the leaps and bounds of the package manager over the last couple years, the ergonomics of using Swift fo
by joshuawright11 5y ago
Exciting stuff.
With async/await landing last week and the leaps and bounds of the package manager over the last couple years, the ergonomics of using Swift for non-iOS work has gotten significantly better. Coupled with the built in safety and elegance of the language I think that, especially for server work, Swift is a very attractive option.
Shameless plug; for these reasons I built a Swift backend framework for fullstack iOS development[1] that we've been using it at my company while going through YC this summer.
It's been very powerful to have mobile and server in the same language and codebase and has helped us (native iOS backgrounds), move quickly.
1: https://github.com/alchemy-swift/alchemy https://github.com/alchemy-swift/alchemy
- jagged-chisel 5y agoHow does Alchemy compare to Vapor?
- joshuawright11 5y agoOh I think Vapor is super powerful, feature packed, and the team has done an amazing job building up and maintaining over the past few years, especially when swift on the server was just getting on it’s legs. That being said, after building with Vapor I felt like there was room for a framework that focused a lot more on convention like Laravel / Rails to keep things lean and fast. Consider ORM APIs… In Vapor require property wrappers around each field, as well as manually entering in the table name, db column the keys map to, and needing to write an initializer. final class Planet: Model { // Name of the table or collection. static let schema = "planets" // Unique identifier for this Planet. @ID(key: .id) var id: UUID? // The Planet's name. @Field(key: "name") var name: String // Creates a new, empty Planet. init() { } // Creates a new Planet with all properties set. init(id: UUID? = nil, name: String) { self.id = id self.name = name } } In Alchemy the table name is inferred to be the type name pluralized, and each db column is inferred from the Swift property name (even mapping camelCase to snakeCase by default). It also supports structs, and thus the automatic initializers. And because it uses Swift.Codable doesn’t have to use expensive reflection APIs to decode, giving a decent performance boost (disclaimer: last time I checked). struct Planet: Model { var id: UUID? var name: String } Similarly with relationships, Vapor requires somewhat verbose string / key path arguments in the property wrappers and supports 1-M M-1 & M-M relationships. final class Star: Model { @Children(for: \.$star) // 1-M var planets: [Planet] @Parent(key: "star_id") // M-1 var star: Star } vs inferring the type and connecting keys, as well as supporting customizing the relationship behavior in Alchemy for things like HasManyThrough, BelongsToThrough, etc. All inferred keys are, of course, overridable in case your db naming convention is different. struct Star: Model { @BelongsTo var star: Star // M-1 @HasMany var planets: [Planet] // 1-M @HasMany var moons: [Moon] // “Has Many Through” static func mapRelations(_ mapper: RelationshipMapper<User>) { // infers mapping from stars.id -> plants.star_id -> planets.id -> moons.planet_id mapper.config(\.$moons).through(“planets”) } } There’s also a bunch more examples of APIs around QueryBuilder, Caching, Jobs, Queues, Redis, Commands, Authentication, Middleware etc[1]. And everything will be converted to async/await in the coming days. 1: https://github.com/alchemy-swift/alchemy/tree/main/Docs#docs https://github.com/alchemy-swift/alchemy/tree/main/Docs#docs
- deergomoo 5y agoAs someone who’s day job is Laravel it’s cool to see that this stuff can be implemented safely and performantly in a strongly typed language.
- pixel_tracing 5y agoI don’t mean to minimize your work (it’s excellent and I always appreciate folks who work on open source), but what makes me wary is the lack of much support: maintenance, Kafka, Database integration wrappers, and so on. Given that I’d much rather go with Vapor, since there is tons of community support there.
- joshuawright11 5y agoAny particular integration you're looking for? Out of the box it supports MySQL & Postgres but it's fully compatible with any external libs built on SwiftNIO, which is the de facto foundation for most Swift server projects.
- syspec 5y ago"New thing not perfect!"
- Zababa 5y agoHow is the performance? Vapor's is terrible, which combined with the small ecosystem makes it a bad choice for backend.
- still_grokking 5y agoIs this the reason IBM stopped its Swift on the server endeavors?
- smoldesu 5y agoPossibly one of them. Swift has just generally had a confusing, lopsided development cycle that has made it extremely hard to build larger/more-abstracted systems on top of it. I'm not quite so sure what breakage looks like these days, but the language only got null-checking a few months ago. I do hope they lay out more groundwork before making the push to non-Apple platforms.
- Redoubts 5y ago> the language only got null-checking a few months ago. ???
- user-the-name 5y ago> but the language only got null-checking a few months ago Are we talking about the same language?
- Zababa 5y agoThere are a few things here https://www.infoq.com/news/2020/01/ibm-stop-work-swift-server/ https://www.infoq.com/news/2020/01/ibm-stop-work-swift-serve.... From what I remember when it was announced, the small ecosystem was mentioned, but not the performance.
- WSSP 5y agoout of curiosity what does terrible means relative to other web server frameworks, and any idea what explains it? I would expect a Swift web framework has at least the potential to be performant