# Querying Models Once you have a [model](models.md) (and optionally a [migration](migrations.md)) you can start querying your database to create, read, update, and delete data. ## Connection The first thing you need to query your database, is a connection to it. Luckily, they are easy to get. You can use either the application or an incoming request to create a database connection. You just need access to the [`DatabaseIdentifier`](provider.md#identifier). ### Request The preferred method for getting access to a database connection is via an incoming request. ```swift router.get(...) { req in return req.withConnection(to: .foo) { db in // use the db here } } ``` The first parameter is the database's [identifier](provider.md#identifier). The second parameter is a closure that accepts a connection to that database. !!! tip Although the closure to `.withConnection(to: ...)` accepts a database _connection_, we often use just `db` for short. The closure is expected to return a `Future`. When this future is completed, the connection will be released back into Fluent's connection pool. This is usually acheived by simply returning the query as we will soon see. ### Application You can also create a database connection using the application. This is useful for cases where you must access the database from outside a request/response event. ```swift let res = app.withConnection(to: .foo) { db in // use the db here } print(res) // Future ``` This is usually done in the [boot section](../getting-started/structure.md#boot) of your application. !!! warning Do not use database connections created by the application in a route closure (when responding to a request). Always use the incoming request to create a connection to avoid threading issues. ## Create To create (save) a model to the database, first initialize an instance of your model, then call `.save(on: )`. ```swift router.post(...) { req in return req.withConnection(to: .foo) { db -> Future in let user = User(name: "Vapor", age: 3) return user.save(on: db).transform(to: user) // Future } } ``` ### Response `.save(on: )` returns a `Future` that completes when the user has finished saving. In this example, we then map that `Future` to a `Future` by calling `.map` and passing in the recently-saved user. You can also use `.map` to return a simple success response. ```swift router.post(...) { req in return req.withConnection(to: .foo) { db -> Future in let user = User(name: "Vapor", age: 3) return user.save(on: db).map(to: HTTPResponse.self) { return HTTPResponse(status: .created) } } } ``` ### Multiple If you have multiple instances to save, do so using an array. Arrays containing only futures behave like futures. ```swift router.post(...) { req in return req.withConnection(to: .foo) { db -> Future in let marie = User(name: "Marie Curie", age: 66) let charles = User(name: "Charles Darwin", age: 73) return [ marie.save(on: db), charles.save(on: db) ].map(to: HTTPResponse.self) { return HTTPResponse(status: .created) } } } ``` ## Read To read models from the database, use `.query()` on the database connection to create a [QueryBuilder](../query-builder). ### All Fetch all instances of a model from the database using `.all()`. ```swift router.get(...) { req in return req.withConnection(to: .foo) { db -> Future<[User]> in return db.query(User.self).all() } } ``` ### Filter Use `.filter(...)` to apply [filters](../query-builder#filters) to your query. ```swift router.get(...) { req in return req.withConnection(to: .foo) { db -> Future<[User]> in return try db.query(User.self).filter(\User.age > 50).all() } } ``` ### First You can also use `.first()` to just get the first result. ```swift router.get(...) { req in return req.withConnection(to: .foo) { db -> Future in return try db.query(User.self).filter(\User.name == "Vapor").first().map(to: User.self) { user in guard let user = user else { throw Abort(.notFound, reason: "Could not find user.") } return user } } } ``` Notice we use `.map(to:)` here to convert the optional user returned by `.first()` to a non-optional user, or we throw an error. ## Update ```swift router.put(...) { req in return req.withConnection(to: .foo) { db -> Future in return db.query(User.self).first().map(to: User.self) { user in guard let user = $0 else { throw Abort(.notFound, reason: "Could not find user.") } return user }.flatMap(to: User.self) { user in user.age += 1 return user.update(on: db).map(to: User.self) { user } } } } ``` Notice we use `.map(to:)` here to convert the optional user returned by `.first()` to a non-optional user, or we throw an error. ## Delete ```swift router.delete(...) { req in return req.withConnection(to: .foo) { db -> Future in return db.query(User.self).first().map(to: User.self) { user in guard let user = $0 else { throw Abort(.notFound, reason: "Could not find user.") } return user }.flatMap(to: User.self) { user in return user.delete(on: db).transfom(to: user) } } } ``` Notice we use `.map(to:)` here to convert the optional user returned by `.first()` to a non-optional user, or we throw an error.