shared/api/endpoints/image.rs
1use super::ApiEndpoint;
2use crate::domain::image::{
3 ImageBrowsePath, ImageCreatePath, ImageDeletePath, ImageGetPath, ImagePutPath, ImageSearchPath,
4 ImageUpdatePath, ImageUploadPath, ImageUploadRequest,
5};
6use crate::error::{EmptyError, MetadataNotFound};
7use crate::{
8 api::Method,
9 domain::image::{
10 CreateResponse, ImageBrowseQuery, ImageBrowseResponse, ImageCreateRequest, ImageResponse,
11 ImageSearchQuery, ImageSearchResponse, ImageUpdateRequest, ImageUploadResponse,
12 },
13};
14
15pub mod recent;
16pub mod tag;
17pub mod user;
18
19/// Get an image by ID.
20///
21/// # Errors:
22///
23/// * [`Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
24/// * [`NotFound`](http::StatusCode::NOT_FOUND) if the image with the requested ID is not found.
25/// * [`Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
26pub struct Get;
27impl ApiEndpoint for Get {
28 type Req = ();
29 type Res = ImageResponse;
30 type Path = ImageGetPath;
31 type Err = EmptyError;
32 const METHOD: Method = Method::Get;
33}
34
35/// Search for images.
36///
37/// The request should be supplied as a URL query string. This is handled by `serde` if using a `to_string` call.
38/// See [`ImageSearchQuery`](crate::domain::image::ImageSearchQuery) for more more usage details.
39///
40/// Ex: `?age_ranges=b873b584-efd0-11eb-b4b7-b791fd521ed5,b8388824-efd0-11eb-b4b7-c335e6a1139f,b778a054-efd0-11eb-b4b7-6f7305d76205&page=0`
41///
42/// # Authorization
43/// Standard
44///
45/// # Errors:
46///
47/// * [`400 - BadRequest`](http::StatusCode::BAD_REQUEST) if the request is invalid.
48/// * [`401 - Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
49/// * [`403 - Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
50/// * [`501 - NotImplemented`](http::StatusCode::NOT_IMPLEMENTED) when the algolia service is disabled.
51pub struct Search;
52impl ApiEndpoint for Search {
53 type Req = ImageSearchQuery;
54 type Res = ImageSearchResponse;
55 type Path = ImageSearchPath;
56 type Err = EmptyError;
57 const METHOD: Method = Method::Get;
58}
59
60/// Browse images.
61///
62/// # Request
63/// The request should be supplied as a URL query string. `kind` field must match the case as
64/// represented in the returned json body (`PascalCase`?).
65///
66/// Ex: `?kind=Canvas&page=0`
67///
68/// # Errors:
69///
70/// * [`400 - BadRequest`](http::StatusCode::BAD_REQUEST) if the request is invalid.
71/// * [`401 - Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
72/// * [`403 - Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
73pub struct Browse;
74impl ApiEndpoint for Browse {
75 type Req = ImageBrowseQuery;
76 type Res = ImageBrowseResponse;
77 type Path = ImageBrowsePath;
78 type Err = EmptyError;
79 const METHOD: Method = Method::Get;
80}
81
82/// Create an image.
83///
84/// # Errors:
85///
86/// * [`400 - BadRequest`](http::StatusCode::BAD_REQUEST) if the request is invalid.
87/// * [`401 - Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
88/// * [`403 - Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
89pub struct Create;
90impl ApiEndpoint for Create {
91 type Req = ImageCreateRequest;
92 type Res = CreateResponse;
93 type Path = ImageCreatePath;
94 type Err = MetadataNotFound;
95 const METHOD: Method = Method::Post;
96}
97
98/// Upload an image.
99///
100/// # Flow:
101///
102/// 1. User requests an upload session URI directly to Google Cloud Storage
103/// a. User uploads to processing bucket
104/// 2. Firestore is notified of `processing = true, ready = false` status at document `uploads/media/global/{id}`
105/// 3. Image is processed and uploaded to the final bucket
106/// 4. Firestore is notified of `processing = true, ready = true` status at document `uploads/media/global/{id}`
107///
108/// # Notes:
109///
110/// * Can be used to update the raw data associated with the image.
111/// * If the client wants to re-upload an image after it has been successfully processed, it must repeat
112/// the entire flow instead of uploading to the same session URI.
113///
114/// # Errors:
115///
116/// * [`400 - BadRequest`](http::StatusCode::BAD_REQUEST) if the request is invalid.
117/// * [`401 - Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid. This may be an API server issue, see #1209.
118/// * [`403 - Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
119/// * [`501 - NotImplemented`](http::StatusCode::NOT_IMPLEMENTED) when the s3/gcs service is disabled.
120pub struct Upload;
121impl ApiEndpoint for Upload {
122 // raw bytes
123 type Req = ImageUploadRequest;
124 type Res = ImageUploadResponse;
125 type Path = ImageUploadPath;
126 type Err = EmptyError;
127 const METHOD: Method = Method::Put;
128}
129
130/// Update an image's metadata.
131pub struct UpdateMetadata;
132impl ApiEndpoint for UpdateMetadata {
133 type Req = ImageUpdateRequest;
134 type Res = ();
135 type Path = ImageUpdatePath;
136 type Err = MetadataNotFound;
137 const METHOD: Method = Method::Patch;
138}
139
140/// Delete an image.
141pub struct Delete;
142impl ApiEndpoint for Delete {
143 type Req = ();
144 type Res = ();
145 type Path = ImageDeletePath;
146 type Err = EmptyError;
147 const METHOD: Method = Method::Delete;
148}
149
150/// Update usage of an Image for metric purposes
151pub struct PutImageUsage;
152impl ApiEndpoint for PutImageUsage {
153 type Req = ();
154 type Res = ();
155 type Path = ImagePutPath;
156 type Err = EmptyError;
157 const METHOD: Method = Method::Patch;
158}