LINUX.ORG.RU

Сообщения smb

 

Снесите тред

Форум — Linux-org-ru

Личная просьба модераторам снести следующий тред: Toolkit для web разработки на Go Всё равно, очевидно, конктруктива не будет, будут только менторы, флуд, а сейчас ещё и длину мерять начнут.

 

smb
()

Toolkit для web разработки на Go

Форум — Web-development

Представляю вашему вниманию toolkit для web разработки на Go. Всё ещё на стадии Proof of Concept (не готов к реальному использованию). Основан на идеях, почерпнутых в баг трекере Revel Framework. Однако, отличается от последнего следующим:

  • Не используется runtime reflection;
  • Отсутствие монолитности;
  • Каждый компонент - независим, может использоваться отдельно от toolkit'а, быть заменён альтернативной реализацией, использоваться с другим фреймворком;
  • Совместимость со стандартной библиотекой и инструментами;
  • Opinionated структура проекта по-умолчанию;
  • 100% кастомизация при необходимости: свой роутер, шаблонизатор, layout проекта и всё, всё, всё.


Главная идея - реализовать toolkit в виде набора независимых утил, каждая из которых делает исключительно свою работу. Из доступного на данный момент:

  • new - опциональная утила, отвечающая за создание нового проекта (та самая opinionated структура по-умолчанию).
  • run - task runner: читает конфигурационный файл в директории проекта, следит за указанными там файлами с целью осуществления в случае их изменения «горячего» (пере)запуска приложения, (пере)компиляции client-side assets (CoffeeScript, SCSS, минификация и конкатенация JS и т.д.) и прочего.
  • generate - утилы, отвечающие за генерацию кода. Могут быть использованы (и по-умолчанию используются) совместно с go generate.
    • handlers - сгенерировать на основе контроллеров пакет со стандартными HTTP Handler функциями, чтобы их можно было использовать со стандартным роутером или любым другим совместимым с ним.
    • views - генерация списка шаблонов во имя type safety.


generate handlers - генерация Handler функций на основе контроллеров.

1. Контроллер - любая стуктура, имеющая action'ы или «магические методы».

2. Action - метод, возвращающий http.Handler в качестве первого параметра.

// Profiles is a sample controller.
type Profiles struct {
}

// Index is a sample action.
func (c *Profiles) Index() http.Handler {
	return c.RenderTemplate(v.Paths.Profiles.IndexHTML)
}

Обратите внимание, action'ы могут иметь любое количество аргументов и возвращать любое количество параметров (до тех пор пока первый - http.Handler):

// List is a sample action that gets 2 arguments and returns 3 results.
func (c *Profiles) List(page int, desc bool) (http.Handler, bool, error) {
}

3. «Магические» action'ы Before и After. Обычные action'ы с той лишь разницей что запускаются автоматически перед и после каждого action'а соответственно.

func (c *App) Before() http.Handler {
	if c.NotAuthorized() {
		return c.RenderTemplate("app/login.html")
	}
	return nil
}

func (c *App) Index() http.Handler {
	...
}

func (c *App) After() http.Handler {
	...
}

4. «Магические» методы Initially и Finally подобны «магическим» action'ам в том, что так же запускаются автоматически с каждым запросом. Подробнее описаны здесь.

5. Наследование. Можно наследовать «магические» action'ы и «магические» методы, используя struct embedding.

type ParentController struct {
}

func (c *ParentController) Before() http.Handler {
	log.Println("ParentController.Before")
	return nil
}

func (c *ParentController) Finally(http.ResponseWriter, *http.Request) (finish bool) {
	log.Println("ParentController.Finally")
	return true // NB!
}

type ChildController struct {
	*ParentController
}

func (c *ChildController) Before() http.Handler {
	log.Println("ChildController.Before")
	return nil
}

func (c *ChildController) Index() http.Handler {
	log.Println("ChildController.Index")
	return c.RenderTemplate(v.Paths.ChildController.IndexHTML)
}

func (c *ChildController) Finally() bool {
	log.Println("ChildController.Finally")
	return false
}

Код выше при запросе к action'у Index напечатает в log следующее:

ParentController.Before
ChildController.Before
ChildController.Index
ParentController.Finally
ChildController.Finally при этом выполнено не будет, т.к. ParentController.Finally вернул finish = true.


generate views - генерация списка файлов

Выше во фрагментах кода использовались следующие конструкции:

return c.RenderTemplate("path/to/dir/file.html")
return c.RenderTemplate(v.Paths.Path.To.Dir.FileHTML)
Второе - экспортируется из автосгенерированного с помощью generate views пакета. Преимущество - отсутствие файла будет обнаружено во время компиляции или запуска конечного приложения, а не во время захода пользователя на сайт.


run - file watcher / task runner

Образец конфигурационного файла:

init:
  - /pass         # Ничего не делать
  - /start build  # Запустить команды асинхронно
  - /single app   # Запустить единственный инстанс команды

  - npm install coffeescript # Выполнить произвольную команду
watch:
  ./controllers:
    - /run build  # Запустить и дождаться результата
    - /single app # Перезапустить ранее запущенный инстанс

build:
  - go build -o ./bin/app github.com/username/project
app: ./bin/app --port $PORT --host $HOST


Чего пока нет:

  • Стандартных контроллеров (аналог middleware в других фреймворках). Имеются Templates и Requests. Но добавлены лишь с тестовой целью, первый делает доступным метод RenderTemplate и поле Context, второй - вызывает ParseForm, чтобы была возможность использовать параметры, переданные, например, методом POST. Сессий, кеша и т.п. нет.
  • Reverse Proxy, чтобы показывать ошибки в окне браузера, а не только в консоли.
  • Есть double array based роутер, основанный на denco router. Но нет генерации роутов и обратных роутов.
  • Сейчас работаю над удобным механизмом генерации форм и валидации полученных от пользователя данных (т.н. autoform): чтобы в одном месте описать форму и использовать это описание и на клиенте и на сервере и при авто валидации.


Как опробовать то что уже есть?

# Установливаем toolkit, убеждаясь, что используем последнюю версию.
go get -u github.com/anonx/sunplate

# Создаём новый проект.
sunplate new bitbucket.com/yourusername/sample

# Запускаем проект.
sunplate run bitbucket.com/yourusername/sample

# Заходим на http://localhost:8080 чтобы увидеть приложение.
# Файлы проекта можно найти в директории
# $GOPATH/src/bitbucket.com/yourusername/sample
Не исключены баги, ошибки и прочее.

 , , ,

smb
()

RSS подписка на новые темы