diff options
author | Federico Igne <git@federicoigne.com> | 2022-07-29 22:51:37 +0100 |
---|---|---|
committer | Federico Igne <git@federicoigne.com> | 2022-07-29 22:51:37 +0100 |
commit | f5611c0bfdc73f76ef5330a17a49d4b5407ae395 (patch) | |
tree | cb2170011592fbf568cf5803de7f3506c328f2e2 | |
parent | 2ec3e5b74b61233f28de99ef36c0bed156864f32 (diff) | |
download | joyce-f5611c0bfdc73f76ef5330a17a49d4b5407ae395.tar.gz joyce-f5611c0bfdc73f76ef5330a17a49d4b5407ae395.zip |
feat(GET /tag/{tags}): add ability to retrieve notes by tag(s)
Placeholder `{tags}` is substituted with one or more tags separated by
a plus sign `+`.
-rw-r--r-- | README.md | 41 |
1 files changed, 36 insertions, 5 deletions
@@ -36,6 +36,8 @@ mod note; | |||
36 | 36 | ||
37 | <<req_get_notes>> | 37 | <<req_get_notes>> |
38 | 38 | ||
39 | <<req_get_tags>> | ||
40 | |||
39 | <<req_post_notes>> | 41 | <<req_post_notes>> |
40 | ``` | 42 | ``` |
41 | 43 | ||
@@ -135,23 +137,22 @@ use actix_web::{HttpResponse,Responder,web,get,post}; | |||
135 | use actix_web::http::header::ContentType; | 137 | use actix_web::http::header::ContentType; |
136 | ``` | 138 | ``` |
137 | 139 | ||
140 | Each request handlers is an *async* function that accepts zero or more parameters, extracted from a request (see [`FromRequest`](https://docs.rs/actix-web/latest/actix_web/trait.FromRequest.html) trait), and returns an [`HttpResponse`](https://docs.rs/actix-web/latest/actix_web/struct.HttpResponse.html). | ||
141 | |||
138 | ## Resources | 142 | ## Resources |
139 | 143 | ||
140 | - [Tutorial](https://web.archive.org/web/20220710213947/https://hub.qovery.com/guides/tutorial/create-a-blazingly-fast-api-in-rust-part-1/) | 144 | - [Tutorial](https://web.archive.org/web/20220710213947/https://hub.qovery.com/guides/tutorial/create-a-blazingly-fast-api-in-rust-part-1/) |
141 | - [Introduction to `actix`](https://actix.rs/docs/getting-started/) | 145 | - [Introduction to `actix`](https://actix.rs/docs/getting-started/) |
142 | 146 | ||
143 | |||
144 | ## GET /notes | 147 | ## GET /notes |
145 | 148 | ||
146 | Each request handlers is an *async* function that accepts zero or more parameters, extracted from a request (see [`FromRequest`](https://docs.rs/actix-web/latest/actix_web/trait.FromRequest.html) trait), and returns an [`HttpResponse`](https://docs.rs/actix-web/latest/actix_web/struct.HttpResponse.html). | 149 | This handler allows to request the full list of notes currently in the system. |
147 | |||
148 | Here we are requesting the list of notes currently in the system. | ||
149 | The function takes 0 parameters and returns a JSON object. | 150 | The function takes 0 parameters and returns a JSON object. |
150 | 151 | ||
151 | ```{#req_get_notes .rust} | 152 | ```{#req_get_notes .rust} |
152 | #[get("/notes")] | 153 | #[get("/notes")] |
153 | pub async fn list() -> HttpResponse { | 154 | pub async fn list() -> HttpResponse { |
154 | let mut notes: Notes; | 155 | let notes: Notes; |
155 | 156 | ||
156 | <<notes_retrieve>> | 157 | <<notes_retrieve>> |
157 | 158 | ||
@@ -163,6 +164,15 @@ pub async fn list() -> HttpResponse { | |||
163 | 164 | ||
164 | ## POST /notes | 165 | ## POST /notes |
165 | 166 | ||
167 | New notes can be added by POSTing a JSON array of `NoteRequest`s of the form | ||
168 | |||
169 | ```json | ||
170 | { | ||
171 | "body": "This is a funny note", | ||
172 | "tags": [ "joyce", "funny", "example" ] | ||
173 | } | ||
174 | ``` | ||
175 | |||
166 | ```{#req_post_notes .rust} | 176 | ```{#req_post_notes .rust} |
167 | #[post("/notes")] | 177 | #[post("/notes")] |
168 | pub async fn add(new_notes: web::Json<NoteRequests>) -> impl Responder { | 178 | pub async fn add(new_notes: web::Json<NoteRequests>) -> impl Responder { |
@@ -180,6 +190,26 @@ pub async fn add(new_notes: web::Json<NoteRequests>) -> impl Responder { | |||
180 | } | 190 | } |
181 | ``` | 191 | ``` |
182 | 192 | ||
193 | ## GET /tag/{tags} | ||
194 | |||
195 | This handler allows to query the set of notes for specific tags. | ||
196 | One or more tags separated by `+` can be passed to the request. | ||
197 | |||
198 | ```{#req_get_tags .rust} | ||
199 | #[get("/tag/{tags}")] | ||
200 | pub async fn get_tags(tags: web::Path<String>) -> HttpResponse { | ||
201 | let tags = tags.split('+').map(|t| t.to_string()).collect::<Vec<_>>(); | ||
202 | |||
203 | let notes: Notes; | ||
204 | <<notes_retrieve>> | ||
205 | let tagged = notes.into_iter().filter(|n| tags.iter().all(|t| n.tags.contains(t))).collect::<Vec<_>>(); | ||
206 | |||
207 | HttpResponse::Ok() | ||
208 | .content_type(ContentType::json()) | ||
209 | .json(tagged) | ||
210 | } | ||
211 | ``` | ||
212 | |||
183 | # The program | 213 | # The program |
184 | 214 | ||
185 | The main program is structured as follows | 215 | The main program is structured as follows |
@@ -209,6 +239,7 @@ async fn main() -> std::io::Result<()> { | |||
209 | App::new() | 239 | App::new() |
210 | .service(note::list) | 240 | .service(note::list) |
211 | .service(note::add) | 241 | .service(note::add) |
242 | .service(note::get_tags) | ||
212 | }) | 243 | }) |
213 | .bind(("127.0.0.1", 8080))? | 244 | .bind(("127.0.0.1", 8080))? |
214 | .run() | 245 | .run() |