├── LICENSE ├── README.md ├── composer.json ├── lang ├── en │ └── responder.php └── fa │ └── responder.php └── src ├── Facades └── Responder.php ├── Responder.php └── ResponderServiceProvider.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Alireza Sajedi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # API Responder - Laravel Response 2 | 3 | **ars/api-responder-laravel** is a Laravel package designed to streamline the creation of standardized API responses. It provides a user-friendly interface for managing API responses, including common status codes and error messages, making API development in Laravel more efficient and consistent. 4 | 5 | ## Features 6 | 7 | - Standardized response structure for successful and error responses. 8 | - Customizable response data with support for links and metadata. 9 | - Easy integration with Laravel through a facade and service provider. 10 | 11 | ## Installation 12 | 13 | You can install the library via Composer. Run the following command: 14 | 15 | ```bash 16 | composer require ars/api-responder-laravel 17 | ``` 18 | # Usage 19 | ## Basic Response 20 | You can use the Responder facade to create standardized API responses. 21 | 22 | ### Example: 23 | ```php 24 | use Responder; 25 | 26 | return Responder::ok($response); 27 | return Responder::setMessage('success')->ok($response); 28 | return Responder::tooManyRequests(); 29 | return Responder::notFound(); 30 | return Responder::unAuthorized(); 31 | 32 | $data = $this->repository->paginate(); 33 | $links = [ 34 | 'next' => $data->nextPageUrl(), 35 | 'prev' => $data->previousPageUrl(), 36 | 'path' => $data->path(), 37 | ]; 38 | $meta = [ 39 | 'total' => $data->total(), 40 | 'current_page' => $data->currentPage(), 41 | 'per_page' => $data->perPage(), 42 | ]; 43 | return Responder::setMeta($meta)->setLinks($links)->ok($data->items()); 44 | 45 | return Responder::setStatusCode(500)->setMessage($e->getMessage())->respond(); 46 | 47 | ``` 48 | 49 | ```json 50 | { 51 | "message": "Operation successful!", 52 | "success": true, 53 | "data": { 54 | "accessToken": "28|PDVEA7z6mUPcbbIybkpiMPJMvy3TLtuWOguiGDGn13c67491", 55 | "tokenType": "Bearer", 56 | "expiresIn": null 57 | } 58 | } 59 | ``` 60 | 61 | ## Additional Methods 62 | - `ok(array $data)`: Return a response 200. 63 | - `respond(array $data)`: Prepare and return a response. 64 | - `setData(array $data)`: Set the response data. 65 | - `setMessage(string $message)`: Set a message for the response. 66 | - `appendData(array $data)`: Append additional data to the response. 67 | - `setErrorCode(mixed $errorCode)`: Set an error code for the response. 68 | - `setStatusCode(int $statusCode)`: Set the HTTP status code for the response. 69 | - `setLinks(array $links)`: Set pagination or other links. 70 | - `setMeta(array $meta)`: Set metadata for the response. 71 | 72 | ## Messages 73 | The library supports various status messages: 74 | 75 | #### If a message key is provided, use `setMessage(string $message)` to set the message. 76 | 77 | - **success:** "Operation successful!" 78 | - **error:** "Operation encountered an error!" 79 | - **validation_error:** "Validation failed!" 80 | - **internal_error:** "Internal server error!" 81 | - **created:** "has been created." 82 | - **updated:** "has been updated." 83 | - **deleted:** "has been deleted." 84 | - **send:** "has been sent." 85 | - **before_posted:** "has already been posted." 86 | - **expire:** "has expired." 87 | - **not_valid:** "is not valid." 88 | - **used:** "has already been used." 89 | - **re_send:** "has been resent." 90 | - **unauthenticated:** "User is not authenticated!" 91 | - **unauthorized:** "User is not authorized to access this resource!" 92 | - **not_found:** "Resource not found!" 93 | - **bad_request:** "Bad request!" 94 | - **to_many_request:** "Too many requests!" 95 | 96 | 97 | ## Contributing 98 | Contributions are welcome! Please adhere to the following guidelines: 99 | 100 | 1. Fork the repository. 101 | 2. Create a feature branch (git checkout -b feature/my-new-feature). 102 | 3. Commit your changes (git commit -am 'Add new feature'). 103 | 4. Push to the branch (git push origin feature/my-new-feature). 104 | 5. Open a Pull Request. 105 | 106 | ## License 107 | This library is licensed under the MIT License. 108 | 109 | ## Contact 110 | For support or questions, please open an issue on GitHub. 111 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ars/api-responder-laravel", 3 | "description": "A library to simplify the creation of standardized API responses.", 4 | "type": "library", 5 | "license": "MIT", 6 | "minimum-stability": "stable", 7 | "require": { 8 | "php": ">=8.0" 9 | }, 10 | "extra": { 11 | "laravel": { 12 | "providers": [ 13 | "Ars\\Responder\\ResponderServiceProvider" 14 | ], 15 | "aliases": { 16 | "Responder": "Ars\\Responder\\Facades\\Responder" 17 | } 18 | } 19 | }, 20 | "homepage": "https://github.com/alireza2000sajedi/api-responder-laravel", 21 | "authors": [ 22 | { 23 | "name": "Alireza Sajedi", 24 | "email": "alireza2000sajedi@gmail.com", 25 | "homepage": "https://github.com/alireza2000sajedi", 26 | "role": "Developer" 27 | } 28 | ], 29 | "autoload": { 30 | "psr-4": { 31 | "Ars\\Responder\\": "src/" 32 | } 33 | }, 34 | "keywords": [ 35 | "api responder", 36 | "laravel responder", 37 | "api", 38 | "response", 39 | "laravel", 40 | "responder", 41 | "http", 42 | "rest", 43 | "json", 44 | "standardized", 45 | "php" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /lang/en/responder.php: -------------------------------------------------------------------------------- 1 | "Operation completed successfully!", 7 | "error" => "An error occurred during the operation.", 8 | "validation_error" => "Validation failed for the provided data.", 9 | "internal_error" => "An internal server error occurred.", 10 | "created" => "The item has been created successfully.", 11 | "updated" => "The item has been updated successfully.", 12 | "deleted" => "The item has been deleted successfully.", 13 | "send" => "The item has been sent successfully.", 14 | "before_posted" => "The item has already been posted.", 15 | "expire" => "The item has expired.", 16 | "not_valid" => "The item is not valid.", 17 | "used" => "The item has already been used.", 18 | "re_send" => "The item has been resent successfully.", 19 | "unauthenticated" => "User is not authenticated.", 20 | "unauthorized" => "User is not authorized to access this resource.", 21 | "not_found" => "The requested resource was not found.", 22 | 'bad_request' => 'The request was invalid or malformed.', 23 | 'to_many_request' => 'Too many requests have been made.', 24 | ]; 25 | -------------------------------------------------------------------------------- /lang/fa/responder.php: -------------------------------------------------------------------------------- 1 | "عملیات با موفقیت انجام شد.", 7 | "error" => "عملیات با خطا مواجه گردید.", 8 | "validation_error" => "خطا در اعتبارسنجی داده‌های ورودی.", 9 | "internal_error" => "خطای داخلی سرور رخ داد.", 10 | "created" => "با موفقیت ایجاد شد.", 11 | "updated" => "با موفقیت به‌روزرسانی شد.", 12 | "deleted" => "با موفقیت حذف گردید.", 13 | "send" => "با موفقیت ارسال شد.", 14 | "before_posted" => "این مورد قبلاً ارسال شده است.", 15 | "expire" => "این مورد منقضی شده است.", 16 | "not_valid" => "این مورد معتبر نمی‌باشد.", 17 | "used" => "این مورد قبلاً استفاده شده است.", 18 | "re_send" => "با موفقیت مجدداً ارسال گردید.", 19 | "unauthenticated" => "شما احراز هویت نشده‌اید.", 20 | "unauthorized" => "شما مجاز به دسترسی به این بخش نیستید.", 21 | "not_found" => "صفحه مورد نظر یافت نشد.", 22 | 'bad_request' => 'درخواست نامعتبر است.', 23 | 'to_many_request' => 'تعداد درخواست‌ها بیش از حد مجاز است.', 24 | ]; 25 | -------------------------------------------------------------------------------- /src/Facades/Responder.php: -------------------------------------------------------------------------------- 1 | data['success'])) { 27 | $response['success'] = $this->data['success']; 28 | } 29 | if (isset($this->data['message'])) { 30 | $response['message'] = $this->data['message']; 31 | } 32 | if (isset($this->data['data'])) { 33 | $response['data'] = $this->data['data']; 34 | } 35 | 36 | // Set meta and links fields after 37 | if (isset($this->data['meta'])) { 38 | $response['meta'] = $this->data['meta']; 39 | } 40 | if (isset($this->data['links'])) { 41 | $response['links'] = $this->data['links']; 42 | } 43 | 44 | return response()->json($response, $this->statusCode); 45 | } 46 | 47 | /** 48 | * Set links data. 49 | * 50 | * @param mixed $links 51 | * @return $this 52 | */ 53 | public function setLinks(mixed $links): static 54 | { 55 | $this->data['links'] = $links; 56 | return $this; 57 | } 58 | 59 | /** 60 | * Set meta data. 61 | * 62 | * @param mixed $meta 63 | * @return $this 64 | */ 65 | public function setMeta(mixed $meta): static 66 | { 67 | $this->data['meta'] = $meta; 68 | return $this; 69 | } 70 | 71 | /** 72 | * Append additional data. 73 | * 74 | * @param array $data 75 | * @return $this 76 | */ 77 | public function appendData(array $data): static 78 | { 79 | $this->data['data'] = array_merge($this->data['data'] ?? [], $data); 80 | return $this; 81 | } 82 | 83 | /** 84 | * Set data. 85 | * 86 | * @param mixed $data 87 | * @return $this 88 | */ 89 | public function setData(mixed $data): static 90 | { 91 | $this->data['data'] = $data; 92 | return $this; 93 | } 94 | 95 | /** 96 | * Set error code. 97 | * 98 | * @param mixed $error 99 | * @return $this 100 | */ 101 | public function setErrorCode(mixed $error): static 102 | { 103 | $this->data['error_code'] = $error; 104 | return $this; 105 | } 106 | 107 | /** 108 | * Set a message. 109 | * 110 | * @param string $message 111 | * @return $this 112 | */ 113 | public function setMessage(string $message): static 114 | { 115 | if (!isset($this->data['message'])) { 116 | if (Lang::has("responder::responder.$message")){ 117 | $message = Lang::get("responder::responder.$message"); 118 | } 119 | $this->data['message'] = $message; 120 | } 121 | return $this; 122 | } 123 | 124 | /** 125 | * Set success status. 126 | * 127 | * @param bool $success 128 | * @return $this 129 | */ 130 | public function setSuccess(bool $success): static 131 | { 132 | $this->data['success'] = $success; 133 | return $this; 134 | } 135 | 136 | /** 137 | * Set HTTP status code. 138 | * 139 | * @param int $statusCode 140 | * @return $this 141 | */ 142 | public function setStatusCode(int $statusCode): static 143 | { 144 | $this->statusCode = $statusCode; 145 | return $this; 146 | } 147 | 148 | /** 149 | * Respond with created status. 150 | * 151 | * @param mixed $data 152 | * @return JsonResponse 153 | */ 154 | public function created(mixed $data = []): JsonResponse 155 | { 156 | return $this->setStatusCode(Response::HTTP_CREATED) 157 | ->setMessage('created') 158 | ->ok($data); 159 | } 160 | 161 | /** 162 | * Respond with updated status. 163 | * 164 | * @param mixed $data 165 | * @return JsonResponse 166 | */ 167 | public function updated(mixed $data = []): JsonResponse 168 | { 169 | return $this->setMessage('updated') 170 | ->ok($data); 171 | } 172 | 173 | /** 174 | * Respond with deleted status. 175 | * 176 | * @return JsonResponse 177 | */ 178 | public function deleted(): JsonResponse 179 | { 180 | return $this->setMessage('deleted') 181 | ->ok(); 182 | } 183 | 184 | /** 185 | * Respond with bad request status. 186 | * 187 | * @return JsonResponse 188 | */ 189 | public function badRequest(): JsonResponse 190 | { 191 | return $this->setStatusCode(Response::HTTP_BAD_REQUEST) 192 | ->setMessage('bad_request') 193 | ->respond(); 194 | } 195 | 196 | /** 197 | * Respond with not found status. 198 | * 199 | * @return JsonResponse 200 | */ 201 | public function notFound(): JsonResponse 202 | { 203 | return $this->setStatusCode(Response::HTTP_NOT_FOUND) 204 | ->setSuccess(false) 205 | ->setMessage('not_found') 206 | ->respond(); 207 | } 208 | 209 | /** 210 | * Respond with internal server error status. 211 | * 212 | * @param mixed $exception 213 | * @return JsonResponse 214 | */ 215 | public function internalError(mixed $exception = null): JsonResponse 216 | { 217 | if ($exception) { 218 | Log::error($exception); 219 | } 220 | return $this->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR) 221 | ->setSuccess(false) 222 | ->setMessage('internal_error') 223 | ->respond(); 224 | } 225 | 226 | /** 227 | * Respond with unauthorized status. 228 | * 229 | * @return JsonResponse 230 | */ 231 | public function unauthorized(): JsonResponse 232 | { 233 | return $this->setStatusCode(Response::HTTP_FORBIDDEN) 234 | ->setSuccess(false) 235 | ->setMessage('unauthorized') 236 | ->respond(); 237 | } 238 | 239 | /** 240 | * Respond with unauthenticated status. 241 | * 242 | * @return JsonResponse 243 | */ 244 | public function unauthenticated(): JsonResponse 245 | { 246 | return $this->setStatusCode(Response::HTTP_UNAUTHORIZED) 247 | ->setSuccess(false) 248 | ->setMessage('unauthenticated') 249 | ->respond(); 250 | } 251 | 252 | /** 253 | * Respond with too many requests status. 254 | * 255 | * @return JsonResponse 256 | */ 257 | public function tooManyRequests(): JsonResponse 258 | { 259 | return $this->setStatusCode(Response::HTTP_TOO_MANY_REQUESTS) 260 | ->setSuccess(false) 261 | ->setMessage('to_many_request') 262 | ->respond(); 263 | } 264 | 265 | /** 266 | * Respond with OK status. 267 | * 268 | * @param mixed $data 269 | * @return JsonResponse 270 | */ 271 | public function ok(mixed $data = []): JsonResponse 272 | { 273 | return $this->setSuccess(true) 274 | ->setMessage('success') 275 | ->setData($data) 276 | ->respond(); 277 | } 278 | 279 | /** 280 | * Respond paginate data. 281 | * 282 | * @param mixed $data 283 | * @return JsonResponse 284 | */ 285 | public function paginate(mixed $data): JsonResponse 286 | { 287 | $links = [ 288 | 'next' => $data->nextPageUrl(), 289 | 'prev' => $data->previousPageUrl(), 290 | 'path' => $data->path(), 291 | ]; 292 | 293 | $meta = [ 294 | 'total' => $data->total(), 295 | 'current_page' => $data->currentPage(), 296 | 'per_page' => $data->perPage(), 297 | ]; 298 | 299 | $items = $data->items(); 300 | 301 | return $this->setMeta($meta)->setLinks($links)->ok($items); 302 | 303 | } 304 | 305 | /** 306 | * Throw a validation exception with the given errors. 307 | * 308 | * @param array $errors 309 | * @throws ValidationException 310 | */ 311 | public function validationError(array $errors = []) 312 | { 313 | throw ValidationException::withMessages($errors); 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /src/ResponderServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadTranslationsFrom(__DIR__.'/../lang', 'responder'); 23 | 24 | $this->app->bind('responder', function () { 25 | return new Responder(); 26 | }); 27 | } 28 | } 29 | --------------------------------------------------------------------------------