DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 967,611 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Ushieru Kokoran
Ushieru Kokoran

Posted on

Dart Frog

Requisitos:

  • Dart >=2.17.0 <3.0.0

Dart Frog 🐸 es un framework web construido sobre Shelf inspirado por Next.JS, Remix y Express.

Otro Angel o Aqueduct?

Solo algunos que planeΓ‘bamos hacer backend con Dart tenΓ­amos la esperanza con estos dos frameworks que al dΓ­a de hoy lamentablemente ya no nos acompaΓ±an.
Sin embargo podemos ver que este nuevo proyecto de llevar Dart al backend (otra vez) esta en buenas manos. Very Good Ventures esta detrΓ‘s de esto por lo que podemos esperar grandes cosas, aunque tampoco dejemos de lado nuestro apoyo como comunidad, actualmente no se aceptan PR por que el roadmap esta ya bien definido, pero issues son bienvenidos.
Asi que hablando de roadmap...

Que nos ofrecen?

βœ… Hot Reload ⚑️
βœ… Dart Dev Tools βš™οΈ
βœ… File System Routing 🚏
βœ… Index Routes πŸ—‚
βœ… Nested Routes πŸͺ†
βœ… Dynamic Routes πŸŒ“
βœ… Middleware πŸ”
βœ… Dependency Injection πŸ’‰
βœ… Production Builds πŸ‘·β€β™‚οΈ
βœ… Docker 🐳
βœ… Static File Support πŸ“

Que tienen en su radar?

🚧 Dart API Client Generation
🚧 Open API Documentation Generation
🚧 DartFrog Testing Library (utilities for unit and e2e testing)
🚧 CLI new command to generate new routes and middleware
🚧 Health Check endpoint for monitoring
🚧 Logger which can be configured to adhere to standard log formats (https://cloud.google.com/run/docs/logging)
🚧 Websocket support
🚧 VSCode/IntelliJ support for DartFrog
🚧 Create a new project
🚧 New Routes
🚧 New Middleware
🚧 Attach Debugger
🚧 CLI deploy command to support deploying to supported cloud platforms (e.g: Cloud Run)

Dart en Backend

Sin duda un proyecto prometedor en el que pongo la confianza para regresar a Dart al backend. En su momento hice un pequeΓ±o blog sobre Dart - From scratch to deploy πŸš€ donde desplegamos en Railway un servidor con Dart. Voy a traer un ejemplo actualizado con Dart Frog, un poco mas complejo para que valga la pena.

Pero mientras tanto que tal si hacemos un pequeΓ±Γ­simo ejemplo de Todo app? Que nada mas registre y liste, solo para no irnos sin programar algo. πŸ§‘β€πŸ’»

Empecemos

Te dejo el repositorio por si solo quieres ver el resultado final.

Definamos un modelo bΓ‘sico de Todo.

// models/todo.dart

import 'package:uuid/uuid.dart';

enum Status { open, inProgress, close }

class Todo {
  Todo(String? id, this.title, this.description, this.status)
      : id = id ?? const Uuid().v4();

  factory Todo.fromJson(Map<String, dynamic> json) {
    return Todo(
      json['id'] as String,
      json['title'] as String,
      json['description'] as String,
      Status.values
          .firstWhere((status) => json['status'] as String == status.name),
    );
  }

  String id;
  String title;
  String description;
  Status status;

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'title': title,
      'description': description,
      'status': status.name
    };
  }
}

Enter fullscreen mode Exit fullscreen mode

Por el momento las rutas se crean al mas puro estilo de Nextjs... πŸ™…β€β™‚οΈ

FutureOr<Response> onRequest(RequestContext context) async {
  switch (context.request.method) {
    case HttpMethod.get:
      return Response(body: 'Get');
    case HttpMethod.post:
      return Response(body: 'Post');
    case HttpMethod.delete:
    case HttpMethod.head:
    case HttpMethod.options:
    case HttpMethod.patch:
    case HttpMethod.put:
      return Response(statusCode: HttpStatus.methodNotAllowed);
  }
}

Enter fullscreen mode Exit fullscreen mode

Y a mi no me encanta ese mΓ©todo asΓ­ que hagamos una pequeΓ±a clase que nos ayude un poco con el boilerplate.

// utils/route_builder.dart

import 'dart:async';
import 'dart:io';

import 'package:dart_frog/dart_frog.dart';

class RouteBuilder {
  final Map<HttpMethod, Handler> _handlers = {};

  FutureOr<Response> hanlder(RequestContext context) {
    if (_handlers.containsKey(context.request.method)) {
      return _handlers[context.request.method]!(context);
    }
    return Response(statusCode: HttpStatus.methodNotAllowed);
  }

  void get(Handler handler) => _handlers[HttpMethod.get] = handler;

  void post(Handler handler) => _handlers[HttpMethod.post] = handler;

  void delete(Handler handler) => _handlers[HttpMethod.delete] = handler;

  void head(Handler handler) => _handlers[HttpMethod.head] = handler;

  void options(Handler handler) => _handlers[HttpMethod.options] = handler;

  void patch(Handler handler) => _handlers[HttpMethod.patch] = handler;

  void put(Handler handler) => _handlers[HttpMethod.put] = handler;
}

Enter fullscreen mode Exit fullscreen mode

Y con todo listo solo creemos nuestra nueva ruta para todos.

// routes/todos.dart

import 'dart:async';

import 'package:dart_frog/dart_frog.dart';
import 'package:uuid/uuid.dart';

import '../models/todo.dart';
import '../utils/route_builder.dart';

final _todos = [];

final _routeBuilder = RouteBuilder()
  ..get((context) {
    return Response.json(body: _todos);
  })
  ..post((context) async {
    final jsonTodo = await context.request.json();
    jsonTodo['status'] = 'open';
    jsonTodo['id'] = const Uuid().v4();

    final newTodo = Todo.fromJson(jsonTodo);
    _todos.add(newTodo);

    return Response.json(body: newTodo.toJson());
  });

FutureOr<Response> onRequest(RequestContext context) async =>
    _routeBuilder.hanlder(context);

Enter fullscreen mode Exit fullscreen mode

Echemos a volar nuestro proyecto.

$ dart_frog dev
Enter fullscreen mode Exit fullscreen mode

termianl

Y ya lo tenemos πŸŽ‰

Get Todos

Post Todos

Integramos react? Hacemos de Dart Frog FullStack?
CuΓ©ntame en los comentarios y Happy Hacking πŸ§‘β€πŸ’»πŸŽ‰

Top comments (0)

DEV has this feature:

Settings

Go to your customization settings to nudge your home feed to show content more relevant to your developer experience level. πŸ›