Git Product home page Git Product logo

apiwrapper's Introduction

Laravel Missed API Response Wrapper

Super fast, lightweight, standard, octane friendly, and high customizable wrapper for Laravel API responses

Laravel Missed API Response Wrapper is a high-quality package that simplifies the creation and management of Laravel API responses. It is very fast, lightweight, octane-friendly and highly customizable. It allows you to easily classify all your API responses, such as those from validators, controllers, and others, with features like status, message, errors, and execution time, all done automatically. In addition, you can also add your own custom values to it, as easily as possible.

Installation

To install Laravel Missed API Response Wrapper, just run the following command:

composer require negartarah/apiwrapper

Configuration

After installing the package, you need to publish its configuration file. To do that, run the following command:

php artisan vendor:publish --provider="Negartarh\APIWrapper\APIResponseServiceProvider"

This will publish the apiwrapper.php configuration file to your config directory and publish localization files to your languages/vendor/apiwrapper directory.

Basic usage

There are two ways of utilizing the package: using the facade, or using the helper functions. On either way you will get the same result, it is totally up to you.

Facade

Example 1.

use Negartarh\APIWrapper\Facades\APIResponse;

...

public function index():\Illuminate\Http\Response
{
    $users = User::latest()->take(10)->get();
    
    # Alias of
    # return APIResponse::success($users);
    return APIResponse::ok($users);
}

Helper functions

Example 1.

use Negartarh\APIWrapper\Facades\APIResponse;

...

public function index():\Illuminate\Http\Response
{
    $users = User::latest()->take(10)->get();
    
    return apiwrapper()->ok($users);
    # or
    return api_response()->ok($users);
}

The result of the above codes is as follows:

{
  "status": 200, // HTTP status code
  "message": "OK", // HTTP message
  "data": [ // Response data
    {
      "id": 1,
      ...
    },
    ...
  ],
  "errors": [], // Errors
  "execution": "13ms", // Serverside exection time
  "version": "3.2.0" // Your application version
}

As you can see, the simple output information has been automatically replaced with the classified information suitable for API requests. Look at the output keys, they are all changeable and editable, but before that, it is better to do more research on the package and get acquainted with its more features.

Advanced Usage

Automatic output based on HTTP standards

Example 1. Storing data

use Illuminate\Support\Facades\Request;
use Negartarh\APIWrapper\Facades\APIResponse;

...

public function create(Request $request):\Illuminate\Http\Response
{
    $user = User::where('email', '=', $request->get('email'))
                  ->firstOrCreate();
                  
    return APIResponse::created($user);
}

The result of the above code is as follows:

{
  "status": 201, // HTTP status code
  "message": "Created", // HTTP message
  "data": { // Response data
    "id": 1,
    ...
  },
  "errors": [], // Errors
  "execution": "10ms", // Serverside exection time
  "version": "3.2.0" // Your application version
}

Example 2. No content

use Illuminate\Support\Facades\Request;
use Negartarh\APIWrapper\Facades\APIResponse;

...

public function index(Request $request):\Illuminate\Http\Response
{
    $posts = Post::all();
    
    if(!is_countable($posts) or count($posts) == 0):
                 
        return APIResponse::noContent();
        
    else:
        ...
}

The result of the above code is as follows:

{
  "status": 204, // HTTP status code
  "message": "No Content", // HTTP message
  "data": [],
  "errors": [],
  "execution": "10ms",
  "version": "3.2.0"
}

Example 3. Validating data

use Illuminate\Http\Exceptions\HttpResponseException;
use Negartarh\APIWrapper\Facades\APIResponse;

class ExampleCaptchaRequest extends FormRequest // example rule class
{
    ...

    /**
     * Handle a failed validation attempt.
     *
     * @param Validator $validator
     * @return HttpResponseException
     */
    public function failedValidation(Validator $validator): HttpResponseException
    {
        # based on RFC: 4918
        return APIResponse::unprocessableEntity($validator->errors());
    }
}

The result of the above code is as follows:

{
  "status": 422, // HTTP status code
  "message": "Unprocessable Entity", // HTTP message
  "errors": {
    "captcha": [
      "The CAPTCHA has expired."
    ]
  },
  "data": [],
  "execution": "41ms",
  "version": "3.2.0"
}

Let’s also take a look at the server response and output headers,

plot plot everything looks great, If it is hard for you to remember the HTTP standards, no problem, pay attention to the next example.

Alternative method

Example 1. Status method

use Illuminate\Http\Exceptions\HttpResponseException;
use Negartarh\APIWrapper\Facades\APIResponse;

class ExampleCaptchaRequest extends FormRequest // example rule class
{
    ...

    /**
     * Handle a failed validation attempt.
     *
     * @param Validator $validator
     * @return HttpResponseException
     */
    public function failedValidation(Validator $validator): HttpResponseException
    {
        return APIResponse::status(413, $validator->errors());
    }
}

and the result is:

{
  "status": 413,
  "message": "Request Entity Too Large",
  "errors": [
    ...
  ],
  "data": [],
  "execution": "17ms",
  "version": "3.2.0"
}

Wait a moment, is not better to customizing the output message? So pay attention to the following example:

Customized messages

Example 1.

use Illuminate\Http\Exceptions\HttpResponseException;
use Negartarh\APIWrapper\Facades\APIResponse;

class ExampleAuthenticationRequest extends FormRequest // example rule class
{
    ...

    /**
     * Handle a failed validation attempt.
     *
     * @param Validator $validator
     * @return HttpResponseException
     */
    public function failedValidation(Validator $validator): HttpResponseException
    {
        # Alias of
        # return APIResponse::status(403, $validator->errors(), 'Where are you looking here?');
        retun APIResponse::forbidden($validator->errors(), 'What are you looking for here?');

    }
}

and guess the result:

{
  "status": 403,
  "message": "What are you looking for here?",
  "errors": {
    ...
  },
  "data": [],
  "execution": "15ms",
  "version": "3.2.0"
}

But wait, there is a better solution, why not implement our own team standard? To do this, just add your own standard to the apiwrapper.php file in the config folder of your project and or make changes to it as needed.

Customized methods

Example 1.

# path/to/project/configuration/dir/apiwrapper.php

return [
    ...
    'methods' => [
        ...
        'accessDenied' => [
            'code' => 403,
            'message' => 'What are you looking for here?',
            'headers' => [
                'Authorization' => 'Failed',
            ],
        ],

and easily use the defined method in your project.

use Illuminate\Support\Facades\Request;
use Negartarh\APIWrapper\Facades\APIResponse;

...

public function login(Request $request):\Illuminate\Http\Response
{
    $user = User::where('access_token', '=', $request->get('access_token'))
                  ->first();
                  
    if($user == null):
        return APIResponse::accessDenied();
    else:
        ...
}

If you pay attention to the above example, you will see that the header value for each status is adjustable, but what to do to adjust it at runtime? To do this, pay attention to the following example:

Adjustable headers

Example 1.

use Illuminate\Support\Facades\Request;
use Negartarh\APIWrapper\Facades\APIResponse;

...

public function login(Request $request):\Illuminate\Http\Response
{
    $user = User::where('access_token', '=', $request->get('access_token'))
                  ->first();
                  
    if($user == null):
        return APIResponse::accessDenied($user, headers: [
                    ...
               ]);
        # or 
        return APIResponse::accessDenied($user)
               ->withHeaders([ ... ]);
    else:
        ...
}

Localization

If your API is multilingual, this package is translatable and has been translated into Persian, Arabic and Turkish. To work with translations, refer to the Laravel documents. for more information, pay attention to the next example:

Example 1. Localized response

use Negartarh\APIWrapper\Facades\APIResponse;

...
App::setLocale('fa');
...

return APIResponse::insufficientStorage();

and the result:

{
  "status": 507,
  "message": "فضای ذخیره سازی ناکافی",
  ...
}

If you do not need to translate the messages, you can disable it through the configuration file.

Example 2. Disabling localization

# path/to/project/configuration/dir/apiwrapper.php

return [
    ...
    'localization' => false,

Customizing responses

To enable, disable or customize default keys in the response, just do it through the configuration file.

Example 1. Disabling default keys

# path/to/project/configuration/dir/apiwrapper.php

return [
    ...
    'fields' => [
        ...
        'execution' => false,

Example 2. change the algorithm

# path/to/project/configuration/dir/apiwrapper.php

return [
    ...
    'fields' => [
        ...
        'version' => fn(mixed $content, int $status, string $message) => env('API_VERSION', 'x.x.x'),

You can get more information on this by studying the configuration file.

Changing the default key names

Like the previous examples, to change the default key names in the response, just do it through the configuration file.

Example 1.

# path/to/project/configuration/dir/apiwrapper.php

return [
    ...
    'replaces' => [
        ...
        'data' => 'content',

result:

{
  "status": 200,
  "message": "OK",
  "content": [ // changed from data to content
    {
      "id": 1,
      ...
    },
    ...
  ],
  "errors": [],
  "execution": "7ms",
  "version": "3.2.0"
}

Adding custom values

To add custom values to the API response, do the following in the configuration file.

Example 1.

# path/to/project/configuration/dir/apiwrapper.php

return [
    ...
    'custom_keys'=>[
        'app'=> 'My Wonderful APP',
        'time'=> fn(mixed $content, int $status, string $message) => \Illuminate\Support\Carbon::now(),

and the result:

{
  "status": 200,
  ...
  "app": "My Wonderful APP",
  "time": "2024-01-05T02:42:10.636571Z"
}

Hints

Example 1. Real-World software development with axios

Back-End:
# API Login Controller
use Negartarh\APIWrapper\Facades\APIResponse;

...

    public function login(LoginRequest $request):\Illuminate\Http\Response
    {
        ...
        
        return APIResponse::ok([
                ...
            ]);
    }

# API LoginRequest Form Request
use Negartarh\APIWrapper\Facades\APIResponse;

...

    public function failedValidation(Validator $validator): HttpResponseException
    {
        return APIResponse::unprocessableEntity($validator->errors());
    }
Front-End:
let isOnRequest = false;

...

async function submitForm() {

    isOnRequest = true;

    await axios.post('api/login', {
        ...
    })
    .then((response) => {
        // if validation passed, you can get response here
        console.log(response.data)
    }).catch((error)=>{
        // if validation failed, you can catch errors here
        console.log(error.response.data)
    }).finally(()=>{
        isOnRequest = false;
    });
}

Built-in methods

In the table below, the predefined methods are given with the HTTP code and message text. All these values are accessible and changeable through the config file.

No. METHOD HTTP STATUS MESSAGE
#0 ok 200 OK
#1 success 200 Success
#2 created 201 Created
#3 accepted 202 Accepted
#4 nonAuthoritativeInformation 203 Non Authoritative Information
#5 noContent 204 No Content
#6 resetContent 205 Reset Content
#7 partialContent 206 Partial Content
#8 multiStatus 207 Multi Status
#9 alreadyReported 208 Already Reported
#10 imUsed 226 IM Used
#11 multipleChoices 300 Multiple Choices
#12 movedPermanently 301 Moved Permanently
#13 found 302 Found
#14 seeOther 303 See Other
#15 notModified 304 Not Modified
#16 useProxy 305 Use Proxy
#17 temporaryRedirect 307 Temporary Redirect
#18 permanentRedirect 308 Permanent Redirect
#19 badRequest 400 Bad Request
#20 unauthorized 401 Unauthorized
#21 paymentRequired 402 Payment Required
#22 forbidden 403 Forbidden
#23 notFound 404 Not Found
#24 methodNotAllowed 405 Method Not Allowed
#25 notAcceptable 406 Not Acceptable
#26 proxyAuthenticationRequired 407 Proxy Authentication Required
#27 requestTimeout 408 Request Timeout
#28 conflict 409 Conflict
#29 gone 410 Gone
#30 lengthRequired 411 Length Required
#31 preconditionFailed 412 Precondition Failed
#32 requestEntityTooLarge 413 Request Entity Too Large
#33 requestURITooLong 414 Request URI Too Long
#34 unsupportedMediaType 415 Unsupported Media Type
#35 requestedRangeNotSatisfiable 416 Requested Range Not Satisfiable
#36 expectationFailed 417 Expectation Failed
#37 unprocessableEntity 422 Unprocessable Entity
#38 locked 423 Locked
#39 failedDependency 424 Failed Dependency
#40 tooEarly 425 Too Early
#41 upgradeRequired 426 Upgrade Required
#42 preconditionRequired 428 Precondition Required
#43 tooManyRequests 429 Too Many Requests
#44 requestHeaderFieldsTooLarge 431 Request Header Fields Too Large
#45 noResponse 444 No Response
#46 unavailableForLegalReasons 451 Unavailable For Legal Reasons
#47 internalServerError 500 Internal Server Error
#48 notImplemented 501 Not Implemented
#49 badGateway 502 Bad Gateway
#50 serviceUnavailable 503 Service Unavailable
#51 gatewayTimeout 504 Gateway Timeout
#52 httpVersionNotSupported 505 HTTP Version Not Supported
#53 variantAlsoNegotiates 506 Variant Also Negotiates
#54 insufficientStorage 507 Insufficient Storage
#55 loopDetected 508 Loop Detected
#56 notExtended 510 Not Extended
#57 networkAuthenticationRequire 511 Network Authentication Require

Requirments

  • php: >= 8.1
  • illuminate/support: *

Contributing

We will be happy if we see PR from you.

License

This is a free package released under the MIT License.

apiwrapper's People

Contributors

negartarh avatar dcblogdev avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.