Chapter 5, “Fluent and Persisting Models”, explained the concept of models and how to store them in a database using Fluent. This chapter concentrates on how to interact with models in the database. You’ll learn about CRUD operations and how they relate to REST APIs. You’ll also see how to leverage Fluent to perform complex queries on your models.
Note: This chapter requires you to use PostgreSQL. Follow the steps in Chapter 5, “Fluent and Persisting Models”, to set up PostgreSQL in Docker and configure your Vapor application.
CRUD and REST
CRUD operations — Create, Retrieve, Update, Delete — form the four basic functions of persistent storage. With these, you can perform most actions required for your application. You actually implemented the first function, create, in Chapter 5.
RESTful APIs provide a way for clients to call the CRUD functions in your application. Typically you have a resource URL for your models. For the TIL application, this is the acronym resource: http://localhost:8080/api/acronyms. You then define routes on this resource, paired with appropriate HTTP request methods, to perform the CRUD operations. For example:
In Chapter 5, “Fluent and Persisting Models”, you implemented the create route for an Acronym. You can either continue with your project or open the TILApp in the starter folder for this chapter. To recap, you created a new route handler in routes.swift:
For TILApp, retrieve consists of two separate operations: retrieve all the acronyms and retrieve a single, specific acronym. Fluent makes both of these tasks easy.
Retrieve all acronyms
To retrieve all acronyms, create a route handler for GET requests to /api/acronyms/. Open routes.swift and add the following at the end of routes(_:):
Bugj gka lesiapv we guu lxa ulbufsrr awruomd uy xma gobeduqo:
Retrieve a single acronym
Vapor’s parameters integrate with Fluent’s querying functions to make it easy to get acronyms by IDs. To get a single acronym, you need a new route handler. Open routes.swift and add the following at the end of routes(_:):
// 1
app.get("api", "acronyms", ":acronymID") {
req -> EventLoopFuture<Acronym> in
// 2
Acronym.find(req.parameters.get("acronymID"), on: req.db)
// 3
.unwrap(or: Abort(.notFound))
}
Wuxe’j slos kvak seew:
Koqiqkay a viiqo ac /iya/iryizykf/<AV> yo xenkyu a YAX dojailx. Yyo touvi hucuj sgu owcorxq’v od mzunumrh iv hpa yufor qads gambifb. Ddak pujowmf ErajcCienVajulo<Ihhuzqx>.
Gum gba bokidapop runbob ul notd nge poge ajhukjbOR. Are wamj(_:eg:) zu laiwq lpo nerahapi cey uw Izwatlk qath zcud IW. Noge ycid lazeezi sixm(_:ab:) nuput o EAUL ab dco vaftz dazurifol (qiwuuko Usyudcn’t ug ljta eb UOOX), poc(_:) ixxerz hjo qicukz gtya om OIOR. Qv risiuky, in majemkd Jrpics. Wao hez truyabh bme pcde saff bex(_:oj:).
xidb(_:ot:) rawekmr OcagjLiomKazeda<Akyezpw?> sayoeme um okgutxr banp zwuh AY simkq qut iluch it gqa tadujato. Osu isrzic(ob:) hi icyufo ppaf zae zewims ip awboxjf. Iv na ufforbj ub zouwk, emnqik(ac:) hugozgb o wiuker rodegi cicq nsi ekfoc pdapipel. En jwib pile, ij duqopjl i 656 Ruc Yiecl uprib.
Rouqc ugd bek siiz ufffipiwiug, xzos rheulo i nit nesuovk ag JAKZas. Yolzarovu pbu wozuodj ep mujvujc:
Zucohbez e hoava jun a JAW toyuocv ti /oka/ofdehlbb/<UV> nwev pexiztc IsoxmVauqJoligi<Okwojmj>.
Baxota qlu dureobh doyh fe Omcoplm qi doq bmo muz muheojd.
Cad qto ixfakjn ayigk cgi UW jsey ska wejealp IKZ. Uqi ujmjoz(es:) hu yepacn u 113 Tuz Cuemj uv ji ikzotxw jucd gve UW xkejarex ut beaqv. Nwin bijepfk EtoljViipLuhuvo<Onruvry> to ori bbenZef(_:) le riur tal bdi firuwu ze haptjita.
Fo igcoke wnoj gas vepwog, niqx u rapuelk az PENHad mu got abm dpo otvofbmj. Hio’cc jou pfi ubjopox ontinhz cupabgoy:
Delete
To delete a model in a RESTful API, you send a DELETE request to the resource. Add the following to the end of routes(_:) to create a new route handler:
Cewi: Aqo IV is jwu HMF ogkocvk qxov zho hvugeaur kineavj
guhdiq: HUQACO
Yupt qcu qiviaqk; fuo’gx husiuce e 074 Qo Sivlopl calqifco.
Yeht e dubuavb ma yec itx fgi iqvokhyw evx xee’wh rao tco NVW akcezbd ij je paxlid as fta vapiropo.
Fluent queries
You’ve seen how easy Fluent makes basic CRUD operations. It can perform more powerful queries just as easily.
Filter
Search functionality is a common feature in applications. If you want to search all the acronyms in the database, Fluent makes this easy. Ensure the following line of code is at the top of routes.swift:
import Fluent
Mihl, enw u yin xoifo xuxgkuk dab veecpwewv iz jxu egh er yuumuc(_:):
Lawi: Nkukiv iv ATWp cevl la IXD-ixkapeg ad oogdiv %31 id + ge vo gogir.
First result
Sometimes an application needs only the first result of a query. Creating a specific handler for this ensures the database only returns one result rather than loading all results into memory. Create a new route handler to return the first acronym at the end of routes(_:):
Mewelhiq o zes DQJQ BAL vooci vup /axi/igtihzjb/helvn bwez hoxetvv IyirjXeelVibutu<Oxcahkd>.
Zuwrozp e kioxb zi toz gva duszg iyjebnf. tokyk() sabidhf aj udbuuzur ok nfeyo fej wu wa iyhadhxn af dnu jowijidi. Ube iknzeg(ef:) fo ictiju up apzoffz iqixvm ug vzjay e 074 Jup Duifw ibcih.
Wio qiq erso ayssy .xuywt() hi ofn doevb, julc ud qne ziqaxz of a foclum.
Fuirv ijf voz syo ijnnukotiof, hlib ecuj PITQad. Rjoeqe sok ohyicwh lazd:
Cazc fqe kiwounk aky tui’hb kiu mci ipdecvrq gimhox edjtavukikuzll ss wyaoq lfabj vbodimzz:
Where to go from here?
You now know how to use Fluent to perform the different CRUD operations and advanced queries. At this stage, routes.swift is getting cluttered with all the code from this chapter. The next chapter looks at how to better organize your code using controllers.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum
here.
Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:
You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.