Do not speak Portuguese? Translate this site with Google or Bing Translator
API Laravel usando PHPUnit

Posted on: October 09, 2023 04:43 PM

Posted by: Renato

Categories: Laravel phpunit

Views: 264

API Laravel usando PHPUnit

 

A execução de testes unitários, de recursos automatizados e de endpoints de API são consideradas algumas das melhores práticas para garantir a implementação adequada de requisitos de software especificados, porque ajudam a garantir o sucesso de tais aplicativos. O teste, sem dúvida, tende a lhe dar 100% de garantia de que quaisquer alterações incrementais e recursos recém-implementados em seu projeto não danificarão o aplicativo. Essa prática costuma ser chamada de Desenvolvimento Orientado a Testes.

Laravel, como um dos frameworks PHP populares, foi construído com testes em mente e vem com um conjunto de testes chamado PHPUnit . PHPUnit é uma estrutura de teste construída para aumentar a produtividade dos desenvolvedores PHP durante o desenvolvimento. Ele foi projetado principalmente para testar código PHP nos menores componentes possíveis, conhecidos como testes unitários, mas também é flexível o suficiente para ser usado além dos testes unitários.

Neste tutorial, adotaremos uma abordagem de desenvolvimento orientado a testes e aprenderemos como testar os endpoints de um projeto de API Laravel. Começaremos escrevendo testes, esperando que falhem. Depois, escreveremos o código para fazer nossos testes passarem. Quando terminarmos, você terá aprendido como realizar testes básicos e estará confiante o suficiente para aplicar esse conhecimento em seus projetos de API Laravel novos ou existentes.

Pré-requisitos

Conhecimento básico de construção de aplicações com Laravel será útil neste tutorial. Além disso, você precisa garantir que instalou o Composer globalmente para gerenciar dependências.

Começando

Nossa API Laravel será usada para criar uma lista e exibir detalhes dos principais CEOs de tecnologia do mundo. Isso é semelhante ao que construímos em um post anterior . Para começar o mais rápido possível, baixe o projeto inicial que contém as estruturas que permitem que nosso aplicativo funcione conforme especificado.

Para começar, execute o seguinte comando para baixar o projeto inicial usando Git :

$ git clone https://github.com/yemiwebby/laravel-api-testing-starter.git

Em seguida, vá para a pasta do novo projeto e instale todas as suas dependências:

// move into the new folder
$ cd laravel-api-testing-starter

//install dependencies
$ composer install

Este projeto de amostra já contém o seguinte:

Em seguida, crie um .envarquivo na raiz do projeto e preencha-o com o conteúdo encontrado no .env.examplearquivo. Você pode fazer isso manualmente ou executando o comando abaixo:

$ cp .env.example .env

Agora gere a chave do aplicativo Laravel para este projeto com:

$ php artisan key:generate

Agora você pode executar o aplicativo php artisan servee prosseguir para http://localhost:8000 para visualizar a página inicial:

Página inicial padrão do Laravel

Não há muito para ver aqui, pois esta é apenas uma página padrão para um projeto Laravel recém-instalado.

Configurando o banco de dados

Para começar a testar, você precisa configurar seu banco de dados de testes. Neste tutorial, simplificaremos as coisas usando um banco de dados SQLite na memória. Oferece a vantagem de maior velocidade para nossos scripts de teste.

Crie um test.sqlitearquivo na databasepasta. Este arquivo será usado para interagir com nosso banco de dados de testes e manter uma configuração separada do banco de dados principal. Em seguida, substitua as variáveis ​​de ambiente do banco de dados .env.testingem seu .envarquivo.

DB_CONNECTION=sqlite
DB_HOST=null
DB_PORT=null
DB_DATABASE=database/test.sqlite
DB_USERNAME=null
DB_PASSWORD=null

Cada teste requer migrações . Precisaremos executar migrações antes de cada teste para construir adequadamente o banco de dados para cada teste. Vamos configurar isso abrindo sua TestCaseclasse base localizada no tests/TestCase.phparquivo e atualizando-a conforme mostrado abaixo:


<?php

namespace Tests;

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Artisan;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication, DatabaseMigrations;

    public function setUp(): void
    {
        parent::setUp();
        Artisan::call('passport:install');
    }
}

Aqui incluímos a DatabaseMigrationscaracterística e adicionamos uma Artisanchamada para instalar o passaporte.

Por último, use o seguinte comando para executar o PHPUnit a partir do terminal:

$ vendor/bin/phpunit

Você verá os resultados conforme mostrado abaixo:

PHPUnit 8.5.4 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 2.03 seconds, Memory: 24.00 MB

OK (2 tests, 2 assertions)

Resultado do teste

A saída acima mostrou que dois testes foram executados com sucesso. Estes foram os testes padrão que vieram instalados com o Laravel. Faremos modificações em breve.

Para tornar o comando de execução do PHPUnit identificável, abra composer.jsono arquivo e adicione o comando de teste à seção de scripts conforme mostrado abaixo:

{
    ...
    "scripts": {
        ...,
        "test": [
            "vendor/bin/phpunit"
        ]
    }
}

Doravante, o comando test estará disponível como composer test.

Criar fábrica de CEO

As fábricas no Laravel fazem uso da biblioteca Faker PHP para gerar dados aleatórios de maneira conveniente para testes. Já que o Laravel vem pré-carregado com uma definição de fábrica para Userclasse. Executaremos o seguinte comando para gerar um para a CEOclasse:

$ php artisan make:factory CEOFactory

Isso criará um novo arquivo nomeado CEOFactory.phpdentro da database/factoriespasta. Abra este novo arquivo e cole o seguinte conteúdo nele:

<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\CEO;
use Faker\Generator as Faker;

$factory->define(CEO::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'company_name' => $faker->unique()->company,
        'year' => $faker->year,
        'company_headquarters' => $faker->city,
        'what_company_does' => $faker->sentence
    ];
});

Especificamos os campos de nossa CEOtabela e usamos a biblioteca Faker para gerar o formato correto de dados aleatórios para todos os campos.

Escrevendo nosso primeiro teste

Vamos começar a escrever nosso teste conforme mencionado anteriormente. Antes disso, exclua os dois arquivos de teste de exemplo nas pastas tests/Featuree, tests/Unitrespectivamente.

Começaremos escrevendo um teste para o processo de autenticação. Isso inclui registro e login. Já temos um controlador criado para esse fim dentro da APIpasta. Então crie o AuthenticationTestarquivo com:

$ php artisan make:test AuthenticationTest

Isso criará o AuthenticationTest.phparquivo dentro da test/Featurepasta. Abra o novo arquivo e substitua seu conteúdo por:

<?php

namespace Tests\Feature;

use App\User;
use Tests\TestCase;

class AuthenticationTest extends TestCase
{
    public function testRequiredFieldsForRegistration()
    {
        $this->json('POST', 'api/register', ['Accept' => 'application/json'])
            ->assertStatus(422)
            ->assertJson([
                "message" => "The given data was invalid.",
                "errors" => [
                    "name" => ["The name field is required."],
                    "email" => ["The email field is required."],
                    "password" => ["The password field is required."],
                ]
            ]);
    }

    public function testRepeatPassword()
    {
        $userData = [
            "name" => "John Doe",
            "email" => "[email protected]",
            "password" => "demo12345"
        ];

        $this->json('POST', 'api/register', $userData, ['Accept' => 'application/json'])
            ->assertStatus(422)
            ->assertJson([
                "message" => "The given data was invalid.",
                "errors" => [
                    "password" => ["The password confirmation does not match."]
                ]
            ]);
    }

    public function testSuccessfulRegistration()
    {
        $userData = [
            "name" => "John Doe",
            "email" => "[email protected]",
            "password" => "demo12345",
            "password_confirmation" => "demo12345"
        ];

        $this->json('POST', 'api/register', $userData, ['Accept' => 'application/json'])
            ->assertStatus(201)
            ->assertJsonStructure([
                "user" => [
                    'id',
                    'name',
                    'email',
                    'created_at',
                    'updated_at',
                ],
                "access_token",
                "message"
            ]);
    }
}

A partir do arquivo acima, os seguintes testes foram escritos:

  • testRequiredFieldsForRegistration: Este teste garante que todos os campos obrigatórios para o processo de registro sejam preenchidos adequadamente.
  • testRepeatPassword: Isso obriga o usuário a repetir senhas. A senha repetida deve corresponder à primeira para que este teste seja aprovado.
  • testSuccessfulRegistration: aqui, criamos um usuário preenchido com dados fictícios para garantir que os usuários possam se inscrever com sucesso.

Agora use o seguinte comando para executar nosso teste usando PHPUnit:

$ composer test

Você verá os resultados abaixo:

> vendor/bin/phpunit
PHPUnit 8.5.4 by Sebastian Bergmann and contributors.

FFF                                                                 3 / 3 (100%)

Time: 259 ms, Memory: 18.00 MB

There were 3 failures:

1) Tests\Feature\AuthenticationTest::testRequiredFieldsForRegistration
Expected status code 422 but received 500.
Failed asserting that 422 is identical to 500.

/Users/yemiwebby/tutorial/twilio/testing/laravel-api-testing/vendor/laravel/framework/src/Illuminate/Testing/TestResponse.php:185
/Users/yemiwebby/tutorial/twilio/testing/laravel-api-testing/tests/Feature/AuthenticationTest.php:14

2) Tests\Feature\AuthenticationTest::testRepeatPassword
Expected status code 422 but received 500.
Failed asserting that 422 is identical to 500.

/Users/yemiwebby/tutorial/twilio/testing/laravel-api-testing/vendor/laravel/framework/src/Illuminate/Testing/TestResponse.php:185
/Users/yemiwebby/tutorial/twilio/testing/laravel-api-testing/tests/Feature/AuthenticationTest.php:34

3) Tests\Feature\AuthenticationTest::testSuccessfulRegistration
Expected status code 201 but received 500.
Failed asserting that 201 is identical to 500.

/Users/yemiwebby/tutorial/twilio/testing/laravel-api-testing/vendor/laravel/framework/src/Illuminate/Testing/TestResponse.php:185
/Users/yemiwebby/tutorial/twilio/testing/laravel-api-testing/tests/Feature/AuthenticationTest.php:53

FAILURES!
Tests: 3, Assertions: 3, Failures: 3.
Script vendor/bin/phpunit handling the test event returned with error code 1

Falhas nos testes

Isso é esperado, pois ainda não implementamos o recurso. Agora vamos escrever o código para fazer nosso teste passar. Abra app/Http/Controllers/API/Auth/AuthController.phpe use o seguinte conteúdo para isso:


<?php

namespace App\Http\Controllers\API\Auth;

use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Http\Request;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|max:55',
            'email' => 'email|required|unique:users',
            'password' => 'required|confirmed'
        ]);

        $validatedData['password'] = bcrypt($request->password);

        $user = User::create($validatedData);

        $accessToken = $user->createToken('authToken')->accessToken;

        return response([ 'user' => $user, 'access_token' => $accessToken, 'message' => 'Register successfully'], 201);
    }
}

Agora corra composer testNeste ponto, nosso teste deve passar.

Teste o ponto final de login

Atualize o AuthenticationTest.phparquivo adicionando mais métodos conforme mostrado aqui:

<?php

namespace Tests\Feature;

use App\User;
use Tests\TestCase;

class AuthenticationTest extends TestCase
{
    ...

    public function testMustEnterEmailAndPassword()
    {
        $this->json('POST', 'api/login')
            ->assertStatus(422)
            ->assertJson([
                "message" => "The given data was invalid.",
                "errors" => [
                    'email' => ["The email field is required."],
                    'password' => ["The password field is required."],
                ]
            ]);
    }

    public function testSuccessfulLogin()
    {
        $user = factory(User::class)->create([
           'email' => '[email protected]',
           'password' => bcrypt('sample123'),
        ]);


        $loginData = ['email' => '[email protected]', 'password' => 'sample123'];

        $this->json('POST', 'api/login', $loginData, ['Accept' => 'application/json'])
            ->assertStatus(200)
            ->assertJsonStructure([
               "user" => [
                   'id',
                   'name',
                   'email',
                   'email_verified_at',
                   'created_at',
                   'updated_at',
               ],
                "access_token",
                "message"
            ]);

        $this->assertAuthenticated();
    }
}

Aqui também criamos um teste para garantir que os campos obrigatórios não sejam deixados vazios pelo usuário que utiliza o testMustEnterEmailAndPassword()método. Dentro do testSuccessfulLogin()método, criamos um usuário fictício para verificar se o usuário foi autenticado com sucesso.

Agora podemos prosseguir e executar o teste novamente usando composer testVocê adivinhou, isso irá falhar mais uma vez. Para garantir que o teste seja aprovado, atualize o AuthController.phparquivo da seguinte maneira:

// app/Http/Controllers/API/Auth/AuthController.php
<?php

namespace App\Http\Controllers\API\Auth;

use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Http\Request;

class AuthController extends Controller
{
    ...

    public function login(Request $request)
    {
        $loginData = $request->validate([
            'email' => 'email|required',
            'password' => 'required'
        ]);

        if (!auth()->attempt($loginData)) {
            return response(['message' => 'Invalid Credentials']);
        }

        $accessToken = auth()->user()->createToken('authToken')->accessToken;

        return response(['user' => auth()->user(), 'access_token' => $accessToken, 'message' => 'Login successfully'], 200);

    }
}

No total, escrevemos cinco testes diferentes e importantes. Alguns dos casos testados incluem o status e a json()estrutura da resposta da API. Na próxima seção, criaremos os conjuntos de testes para endpoints do CEO.

Escrevendo testes para os endpoints do CEO

Nesta seção, começaremos criando um novo arquivo de teste para hospedar os scripts de teste para os endpoints CEO. Use o seguinte comando para esse propósito:

$ php artisan make:test CEOTest

O comando anterior criará um novo arquivo de teste denominado CEOTest.phparquivo dentro da tests/Featurepasta. Abra-o e substitua seu conteúdo pelo seguinte:

<?php

namespace Tests\Feature;

use App\CEO;
use App\User;
use Tests\TestCase;

class CEOTest extends TestCase
{
    public function testCEOCreatedSuccessfully()
    {
        $user = factory(User::class)->create();
        $this->actingAs($user, 'api');

        $ceoData = [
            "name" => "Susan Wojcicki",
            "company_name" => "YouTube",
            "year" => "2014",
            "company_headquarters" => "San Bruno, California",
            "what_company_does" => "Video-sharing platform"
        ];

        $this->json('POST', 'api/ceo', $ceoData, ['Accept' => 'application/json'])
            ->assertStatus(201)
            ->assertJson([
                "ceo" => [
                    "name" => "Susan Wojcicki",
                    "company_name" => "YouTube",
                    "year" => "2014",
                    "company_headquarters" => "San Bruno, California",
                    "what_company_does" => "Video-sharing platform"
                ],
                "message" => "Created successfully"
            ]);
    }

    public function testCEOListedSuccessfully()
    {

        $user = factory(User::class)->create();
        $this->actingAs($user, 'api');

        factory(CEO::class)->create([
            "name" => "Susan Wojcicki",
            "company_name" => "YouTube",
            "year" => "2014",
            "company_headquarters" => "San Bruno, California",
            "what_company_does" => "Video-sharing platform",
        ]);

        factory(CEO::class)->create([
            "name" => "Mark Zuckerberg",
            "company_name" => "FaceBook",
            "year" => "2004",
            "company_headquarters" => "Menlo Park, California",
            "what_company_does" => "The world's largest social network",
        ]);

        $this->json('GET', 'api/ceo', ['Accept' => 'application/json'])
            ->assertStatus(200)
            ->assertJson([
                "ceos" => [
                    [
                        "id" => 1,
                        "name" => "Susan Wojcicki",
                        "company_name" => "YouTube",
                        "year" => "2014",
                        "company_headquarters" => "San Bruno, California",
                        "what_company_does" => "Video-sharing platform"
                    ],
                    [
                        "id" => 2,
                        "name" => "Mark Zuckerberg",
                        "company_name" => "FaceBook",
                        "year" => "2004",
                        "company_headquarters" => "Menlo Park, California",
                        "what_company_does" => "The world's largest social network"
                    ]
                ],
                "message" => "Retrieved successfully"
            ]);
    }
}

Isso pode parecer um pouco assustador, mas é semelhante aos testes que escrevemos anteriormente. Vamos decompô-lo. Criamos dois métodos diferentes:

  • testCEOCreatedSuccessfully: Para testar se podemos criar um registro de CEO usando os dados apropriados.
  • testCEOListedSuccessfully: Aqui garantimos que a lista de CEOs criados possa ser recuperada e devolvida como resposta.

Ao contrário do AuthenticationTest, o . CEOTestfoi escrito para endpoints protegidos por um middleware chamado auth:apiPara garantir que o usuário fictício recém-criado seja autenticado antes de acessar os endpoints, autenticamos $this->actingAs($user, 'api')e autorizamos tal usuário a ter acesso para realizar qualquer uma das atividades CRUD (criar, ler, atualizar e excluir).

Agora execute o teste novamente usando composer testVocê verá que ele falha novamente. Até agora, tenho certeza de que você entende por que isso não deu certo. Caso você ainda esteja aprendendo a lógica desses testes, precisamos preencher o CEOController.phparquivo com o código apropriado para fazer o teste passar.

Atualizar o CEOController

Navegue até o app/Http/Controllers/API/CEOController.phparquivo e use o seguinte conteúdo para ele:


<?php

namespace App\Http\Controllers\API;

use App\CEO;
use App\Http\Controllers\Controller;
use App\Http\Resources\CEOResource;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class CEOController extends Controller
{
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $data = $request->all();

        $validator = Validator::make($data, [
            'name' => 'required|max:255',
            'company_name' => 'required|max:255',
            'year' => 'required|max:255',
            'company_headquarters' => 'required|max:255',
            'what_company_does' => 'required'
        ]);

        if($validator->fails()){
            return response(['error' => $validator->errors(), 'Validation Error']);
        }

        $ceo = CEO::create($data);

        return response([ 'ceo' => new CEOResource($ceo), 'message' => 'Created successfully'], 201);
    }


    public function index()
    {
        $ceos = CEO::all();

        return response([ 'ceos' => CEOResource::collection($ceos), 'message' => 'Retrieved successfully'], 200);
    }
}

Aqui, criamos métodos para armazenar os registros de um novo CEO e também recuperar a lista CEOsdo banco de dados respectivamente. Você pode executar o teste novamente e descobrir que desta vez ele foi aprovado.

Por último, vamos adicionar mais testes para recuperar, atualizar e também excluir os detalhes de um CEO específico. Abra o CEOTest.phparquivo e adicione os seguintes métodos:

<?php

namespace Tests\Feature;

use App\CEO;
use App\User;
use Tests\TestCase;

class CEOTest extends TestCase
{
    ...

    public function testRetrieveCEOSuccessfully()
    {
        $user = factory(User::class)->create();
        $this->actingAs($user, 'api');

        $ceo = factory(CEO::class)->create([
            "name" => "Susan Wojcicki",
            "company_name" => "YouTube",
            "year" => "2014",
            "company_headquarters" => "San Bruno, California",
            "what_company_does" => "Video-sharing platform"
        ]);

        $this->json('GET', 'api/ceo/' . $ceo->id, [], ['Accept' => 'application/json'])
            ->assertStatus(200)
            ->assertJson([
                "ceo" => [
                    "name" => "Susan Wojcicki",
                    "company_name" => "YouTube",
                    "year" => "2014",
                    "company_headquarters" => "San Bruno, California",
                    "what_company_does" => "Video-sharing platform"
                ],
                "message" => "Retrieved successfully"
            ]);
    }

    public function testCEOUpdatedSuccessfully()
    {
        $user = factory(User::class)->create();
        $this->actingAs($user, 'api');

        $ceo = factory(CEO::class)->create([
            "name" => "Susan Wojcicki",
            "company_name" => "YouTube",
            "year" => "2014",
            "company_headquarters" => "San Bruno, California",
            "what_company_does" => "Video-sharing platform"
        ]);

        $payload = [
            "name" => "Demo User",
            "company_name" => "Sample Company",
            "year" => "2014",
            "company_headquarters" => "San Bruno, California",
            "what_company_does" => "Video-sharing platform"
        ];

        $this->json('PATCH', 'api/ceo/' . $ceo->id , $payload, ['Accept' => 'application/json'])
            ->assertStatus(200)
            ->assertJson([
                "ceo" => [
                    "name" => "Demo User",
                    "company_name" => "Sample Company",
                    "year" => "2014",
                    "company_headquarters" => "San Bruno, California",
                    "what_company_does" => "Video-sharing platform"
                ],
                "message" => "Updated successfully"
            ]);
    }

    public function testDeleteCEO()
    {
        $user = factory(User::class)->create();
        $this->actingAs($user, 'api');

        $ceo = factory(CEO::class)->create([
            "name" => "Susan Wojcicki",
            "company_name" => "YouTube",
            "year" => "2014",
            "company_headquarters" => "San Bruno, California",
            "what_company_does" => "Video-sharing platform"
        ]);

        $this->json('DELETE', 'api/ceo/' . $ceo->id, [], ['Accept' => 'application/json'])
            ->assertStatus(204);
    }

}

Os testes escritos acima foram usados ​​para direcionar os registros de um determinado CEO, passando um único idcomo parâmetro para os api/ceoendpoints usando os verbos HTTP apropriados (ou seja GETPATCHDELETE).

A seguir, atualizaremos o CEOControllerarquivo para garantir que os novos testes também sejam aprovados. Abra app/Http/Controllers/API/CEOController.phpe inclua os seguintes métodos:

<?php

namespace App\Http\Controllers\API;

use App\CEO;
use App\Http\Controllers\Controller;
use App\Http\Resources\CEOResource;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class CEOController extends Controller
{
    ...

    /**
     * Display the specified resource.
     *
     * @param  \App\CEO  $ceo
     * @return \Illuminate\Http\Response
     */
    public function show(CEO $ceo)
    {
        return response([ 'ceo' => new CEOResource($ceo), 'message' => 'Retrieved successfully'], 200);

    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\CEO  $ceo
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, CEO $ceo)
    {

        $ceo->update($request->all());

        return response([ 'ceo' => new CEOResource($ceo), 'message' => 'Updated successfully'], 200);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param \App\CEO $ceo
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */


    public function destroy(CEO $ceo)
    {
        $ceo->delete();

        return response(['message' => 'Deleted'], 204);
    }
}

Os métodos criados aqui irão recuperar, atualizar e excluir os registros de um CEO do banco de dados.

Agora podemos executar o comando de teste pela última vez usando composer teste você verá a seguinte saída:

> vendor/bin/phpunit
PHPUnit 8.5.4 by Sebastian Bergmann and contributors.

..........                                                        10 / 10 (100%)

Time: 915 ms, Memory: 32.00 MB

OK (10 tests, 35 assertions)

Conclusão

Neste tutorial, pudemos usar uma abordagem de desenvolvimento orientado a testes para escrever alguns testes para os endpoints em nosso projeto de API Laravel. Você apreciará ainda mais o desenvolvimento orientado a testes quando descobrir que, uma vez adicionado mais recursos, as novas implementações não interrompem de forma alguma o funcionamento de sua base de código existente.

A base de código completa do tutorial pode ser encontrada aqui no GitHub . Você pode explorar, adicionar mais testes e escrever o código que permitirá que seu teste seja aprovado de acordo.

Olususi Oluyemi é um entusiasta de tecnologia, fanático por programação e um viciado em desenvolvimento web que adora adotar novas tecnologias.

Avalie esta postagem
AUTORES

1

Share

Donate to Site


About Author

Renato

Developer

Add a Comment

Blog Search


Categories

OUTROS (16) Variados (109) PHP (133) Laravel (171) Black Hat (3) front-end (29) linux (114) postgresql (39) Docker (28) rest (5) soap (1) webservice (6) October (1) CMS (2) node (7) backend (13) ubuntu (56) devops (25) nodejs (5) npm (3) nvm (1) git (8) firefox (1) react (7) reactnative (5) collections (1) javascript (7) reactjs (8) yarn (0) adb (1) Solid (2) blade (3) models (1) controllers (0) log (1) html (2) hardware (3) aws (14) Transcribe (2) transcription (1) google (4) ibm (1) nuance (1) PHP Swoole (5) mysql (31) macox (4) flutter (1) symfony (1) cor (1) colors (2) homeOffice (2) jobs (3) imagick (2) ec2 (1) sw (1) websocket (2) markdown (1) ckeditor (1) tecnologia (14) faceapp (1) eloquent (14) query (4) sql (40) ddd (3) nginx (9) apache (4) certbot (1) lets-encrypt (3) debian (12) liquid (1) magento (2) ruby (1) LETSENCRYPT (1) Fibonacci (1) wine (1) transaction (1) pendrive (1) boot (1) usb (1) prf (1) policia (2) federal (1) lucena (1) mongodb (4) paypal (1) payment (1) zend (1) vim (4) ciencia (6) js (1) nosql (1) java (1) JasperReports (1) phpjasper (1) covid19 (1) saude (1) athena (1) cinnamon (1) phpunit (2) binaural (1) mysqli (3) database (42) windows (6) vala (1) json (2) oracle (1) mariadb (4) dev (12) webdev (24) s3 (4) storage (1) kitematic (1) gnome (2) web (2) intel (3) piada (1) cron (2) dba (18) lumen (1) ffmpeg (2) android (2) aplicativo (1) fedora (2) shell (4) bash (3) script (3) lider (1) htm (1) csv (1) dropbox (1) db (3) combustivel (2) haru (1) presenter (1) gasolina (1) MeioAmbiente (1) Grunt (1) biologia (1) programming (22) performance (3) brain (1) smartphones (1) telefonia (1) privacidade (1) opensource (3) microg (1) iode (1) ssh (3) zsh (2) terminal (3) dracula (1) spaceship (1) mac (2) idiomas (1) laptop (2) developer (37) api (5) data (1) matematica (1) seguranca (2) 100DaysOfCode (9) hotfix (1) documentation (1) laravelphp (10) RabbitMQ (3) Elasticsearch (1) redis (2) Raspberry (4) Padrao de design (4) JQuery (1) angularjs (4) Dicas (43) Kubernetes (3) vscode (2) backup (1) angular (3) servers (2) pipelines (1) AppSec (1) DevSecOps (4) rust (1) RustLang (1) Mozilla (1) algoritimo (1) sqlite (1) Passport (2) jwt (5) security (2) translate (1) kube (2) iot (1) politica (2) bolsonaro (1) flow (1) podcast (1) Brasil (1) containers (3) traefik (1) networking (1) host (1) POO (2) microservices (2) bug (1) cqrs (1) arquitetura (3) Architecture (4) sail (3) militar (1) artigo (1) economia (1) forcas armadas (1) ffaa (1) autenticacao (2) autorizacao (2) authentication (4) authorization (3) NoCookies (1) wsl (4) memcached (1) macos (2) unix (2) kali-linux (1) linux-tools (5) apple (1) noticias (2) composer (1) rancher (1) k8s (1) escopos (1) orm (1) jenkins (4) github (5) gitlab (3) queue (1) Passwordless (1) sonarqube (1) phpswoole (1) laraveloctane (1) Swoole (1) Swoole (1) octane (1) Structurizr (1) Diagramas (1) c4 (1) c4-models (1) compactar (1) compression (1) messaging (1) restfull (1) eventdrive (1) services (1) http (1) Monolith (1) microservice (1) historia (1) educacao (1) cavalotroia (1) OOD (0) odd (1) chatgpt (1) openai (3) vicuna (1) llama (1) gpt (1) transformers (1) pytorch (1) tensorflow (1) akitando (1) ia (1) nvidia (1) agi (1) guard (1) multiple_authen (2) rpi (1) auth (1) auth (1) livros (2) ElonMusk (2) Oh My Zsh (1) Manjaro (1) BigLinux (2) ArchLinux (1) Migration (1) Error (1) Monitor (1) Filament (1) LaravelFilament (1) replication (1) phpfpm (1) cache (1) vpn (1) l2tp (1) zorin-os (1) optimization (1) scheduling (1) monitoring (2) linkedin (1) community (1) inteligencia-artificial (2) wsl2 (1) maps (1) API_KEY_GOOGLE_MAPS (1) repmgr (1) altadisponibilidade (1) banco (1) modelagemdedados (1) inteligenciadedados (4) governancadedados (1) bancodedados (2) Observability (1) picpay (1) ecommerce (1) Curisidades (1) Samurai (1) KubeCon (1) GitOps (1) Axios (1) Fetch (1) Deepin (1) vue (4) nuxt (1) PKCE (1) Oauth2 (2) webhook (1) TypeScript (1) tailwind (1) gource (2)

New Articles



Get Latest Updates by Email