Создание блога на Dart. Часть 2.

Создание блога на Dart. Часть 1.
Создание блога на Dart. Часть 2.
Создание блога на Dart. Часть 3.
Роутинг
Роутинг я реализовал просто — обработкой запросов занимаются контроллеры, каждый из которых сам решает, может он обработать запрос или нет. Запрос обрабатывается первым подходящим контроллером.
Класс базового контроллера:
abstract class ControllerBase {
Future processRequest(HttpRequest request);
Future<bool> canProcessRequest(HttpRequest request);
}
Базовый класс для контроллеров, возвращающих HTML:
abstract class HttpController extends ControllerBase {
Future processRequest(HttpRequest request) async {
request.response.headers.contentType = ContentType.HTML;
}
}
Класс контроллера, отдающего содержимое поста по пермалинку:
class PostController extends HttpController {
PostRepository postRepository = injector.get(PostRepository);
PostController() {}
Future processRequest(HttpRequest request) async {
await super.processRequest(request);
var requestPermalink = StringUtils.Trim(request.requestedUri.path, '/');
postRepository.getAllPosts().then((List<Post> posts) {
var post = posts.where((p) => p.permalink == requestPermalink).single;
request.response
..write(post.body)
..close();
});
}
Future<bool> canProcessRequest(HttpRequest request) {
var requestPermalink = StringUtils.Trim(request.requestedUri.path, '/');
return postRepository.getAllPosts().then((List<Post> posts) {
return posts.any((p) => p.permalink == requestPermalink);
});
}
}
Урл для этого контроллера выглядит так: /permalink
Из репозитория постов получаются все посты, из них выбирается единственный с соответствующим пермалинком и в ответ пишется содержимое поста. Верстку и шаблонизацию пока не делал, хотя пара шаблонизаторов для Dart есть.
Класс контроллера, отдающего список постов:
class ListController extends HttpController {
PostRepository postRepository = injector.get(PostRepository);
static const int postsPerPage = 2;
Future processRequest(HttpRequest request) async {
await super.processRequest(request);
int pageNum = int.parse(request.requestedUri.queryParameters["p"]);
List<Post> posts = await postRepository.getAllPosts();
List<Post> shownPosts =
posts.skip(postsPerPage * (pageNum - 1)).take(postsPerPage).toList();
shownPosts.forEach((Post post) {
request.response
..write("<h1>${post.title}</h1><br>${post.body}<br><br><br>");
});
request.response.close();
}
Future<bool> canProcessRequest(HttpRequest request) async {
var requestlink = StringUtils.Trim(request.requestedUri.path, '/');
if (requestlink != 'list') return false;
if (!request.requestedUri.queryParameters.containsKey("p")) return false;
return true;
}
}
Полезные мелочи
В базовой библиотеке Dart пока не хватает всех привычных полезных функций, так что trim() для строки пришлось делать самому:
class StringUtils {
static String Trim(String string, String part) {
if (part.length != 1)
throw new ArgumentError('part.length should be equal to 1');
String result = string;
if (result.startsWith(part))
result = result.substring(1);
if (result.endsWith(part))
result = result.substring(0, result.length - 1);
return result;
}
}