Compare With Laravel
Goravel follows the structure of Laravel, so the concepts, the facades and most method names carry over. The table below shows the same task in both frameworks. Where one of them does not have a feature, it says so.
| Feature | Laravel | Goravel |
|---|---|---|
| Artisan Console | php artisan key:generate | ./artisan key:generate |
| Authentication | Auth::login($user) | facades.Auth(ctx).Login(&user) |
| Authorization | Gate::allows('update-post', $post) | facades.Gate().Allows("update-post", map[string]any{"post": post}) |
| Cache | Cache::put('key', 'value', 60) | facades.Cache().Put("key", "value", time.Minute) |
| Carbon | Carbon::now()->addDays(1) | carbon.Now().AddDays(1) |
| Config | config('app.name') | facades.Config().GetString("app.name") |
| Crypt | Crypt::encryptString('text') | facades.Crypt().EncryptString("text") |
| DB | DB::table('users')->get() | facades.DB().Table("users").Get(&users) |
| Event | OrderShipped::dispatch() | facades.Event().Job(&events.OrderShipped{}, []event.Arg{}).Dispatch() |
| Factory | User::factory()->make() | facades.Orm().Factory().Make(&user) |
| File Storage | Storage::put('file.txt', 'content') | facades.Storage().Put("file.txt", "content") |
| Hash | Hash::make('password') | facades.Hash().Make("password") |
| HTTP Client | Http::get('https://example.com') | facades.Http().Get("https://example.com") |
| Localization | __('messages.welcome') | facades.Lang(ctx).Get("messages.welcome") |
| Logging | Log::info('message') | facades.Log().Info("message") |
Mail::to('user@example.com')->send(new OrderShipped()) | facades.Mail().To([]string{"user@example.com"}).Send() | |
| Migrations | php artisan migrate | ./artisan migrate |
| Mock | Cache::shouldReceive('get') | mock.Factory().Cache() |
| ORM | User::find(1) | facades.Orm().Query().Find(&user, 1) |
| Package Development | $this->loadViewsFrom($path, 'courier') | facades.View().LoadViewsFrom("/path/to/package/views") |
| Process | Process::run('ls -la') | facades.Process().Run("ls", "-la") |
| Queue | SendEmail::dispatch() | facades.Queue().Job(&jobs.SendEmail{}, []queue.Arg{}).Dispatch() |
| Rate Limiting | RateLimiter::for('global', ...) | facades.RateLimiter().For("global", ...) |
| Routing | Route::get('/', [Controller::class, 'index']) | facades.Route().Get("/", controller.Index) |
| Seeder | $this->call([UserSeeder::class]) | facades.Seeder().Call([]seeder.Seeder{&UserSeeder{}}) |
| Session | session(['key' => 'value']) | ctx.Request().Session().Put("key", "value") |
| Task Scheduling | Schedule::command('emails:send')->daily() | facades.Schedule().Command("emails:send").Daily() |
| Testing | $this->get('/tasks') | s.Http(s.T()).Get("/tasks") |
| Validation | $request->validate([...]) | ctx.Request().ValidateRequest(&storePost) |
| View | view('welcome') | ctx.Response().View().Make("welcome.tmpl") |
| Grpc | Not built in | facades.Grpc().Connect("user") |
| Telemetry | Not built in | facades.Telemetry().Tracer("app").Start(ctx, "order.process") |
| Notifications | $user->notify(new InvoicePaid()) | Not yet |
| Broadcasting | broadcast(new OrderShipped($order)) | Not yet |
| Livewire | <livewire:counter /> | Not yet |