如我们承诺的, Phoenix 1.3.0 的第一个版本发布了! 这个版本专注于改进后的项目结构中的代码生成, 对于伞型项目的一流支持, 以及新的脚手架, 使得 phoenix 成为你的更大的 Elixir 应用的 web 接口. 我们还在 Phoenix.Controller 中包含了新的 action_fallback
功能, 能让你把普通的数据结构转换成合法的回应. 在实践中, 这能够为你提供一个单独的 plug 来替代重复的代码, 让你的的 controller 代码更加清晰. 这对 JSON API controller 十分友好.
如果你对这些修改和设计意图感兴趣, 可以看我在 LonestarElixir 上的keynote: (https://www.youtube.com/watch...
为了使用新的 phx.new
来生成项目, 你可以使用以下命令来安装 archive:
$ mix archive.install https://github.com/phoenixfra...
如往常一样, 我们提供了对 1.2.x 版本的项目进行迁移的详细的更新向导 (https://gist.github.com/chris...
1.3.0 是向后兼容的, 所以你可以简单地将你的 mix.exs 中的 :phoenix 依赖更新到 "~> 1.3". 对于想接收新的规则的人们, 更像向导会一步一步地引导你. 在更新之前, 最好先观看一下 keynote, 或者阅读以下的设计意图.
Phoenix 1.3 - 设计意图
总结了过去两年的经验, 我们设计了更好的项目结构和代码生成器. 包括把 web
文件夹移动到 lib
中, 避免了任何特别的目录, 同时引入了新的 Web
模块名, 更好地表明 Phoenix 相关的 web 模块只是你更大的 Elixir 应用的 web 接口. 伴随新的项目结构, 还有新的 phx.gen.html
和 phx.gen.json
生成器, 能够将你的 web 接口独立出来.
Contexts (上下文)
当你使用 phx.gen.html|json
来生成 HTML 或 JSON 资源时, Phoenix 会在一个 Context 中生成代码, 就是一个命名好的模块, 包含了命名好的函数, 将 API 与你的应用的其它部分分清边界.
例如, 要生成一个 user
资源, 我们运行:
$ mix phx.gen.html Accounts User users email:string:unique
注意, "Accounts" 是一个新的参数. 这是一个用来存放你的应用中关于 user accounts 的业务逻辑的 context 模块. 我们截取一部分它生成的代码:
# lib/my_app/web/controllers/user_controller.ex
defmodule MyApp.Web.UserController do
...
alias MyApp.Accounts
def index(conn, _params) do
users = Accounts.list_users()
render(conn, "index.html", users: users)
end
def create(conn, %{"user" => user_params}) do
case Accounts.create_user(user_params) do
{:ok, user} ->
conn
|> put_flash(:info, "user created successfully.")
|> redirect(to: user_path(conn, :show, user))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
...
end
# lib/my_app/accounts/accounts.ex
defmodule MyApp.Accounts do
@moduledoc """
The boundary for the Accounts system.
"""
alias MyApp.Accounts.User
def list_users do
Repo.all(User)
end
def create_user(attrs \\ %{}) do
%User{}
|> user_changeset(attrs)
|> Repo.insert()
end
...
end
它还会在 lib/my_app/accounts/user.ex
文件中生成一个 Ecto schema. 注意我们的 controller 是如何在系统中调用 API 来创造或获取 users 的. 我们仍然使用 Ecto, 但是数据库和应用逻辑被分开了. 我们的 web 接口不需要了解 user 的存储或数据库表现. Accounts 模块可以将 users 存储在 agent, ETS 等等, 我们的 controller 代码也不需要改变.
通过让用户来思考他们的 API 的边界, 我陪吗最终得到了更可维护, 结构良好的代码. 此外, 我们只需要探索应用的目录结构就可以了解应用的功能:
lib/my_app
├── accounts
│ ├── user.ex
│ └── accounts.ex
├── sales
│ ├── ticket.ex
│ ├── manager.ex
│ └── sales.ex
├── repo.ex
└── web
├── channels
├── controllers
├── templates
└── views
只需要看一看目录结构, 我们就可以知道这个应用有着用户账号系统, 以及销售系统. 我们还可以通过 sales.ex
和 accounts.ex
模块推断出这些系统之间有着一个天然的边界. 我们可以不看一行代码就获知这些. 而之前的 web/models
结构, 没有揭示任何文件之间的关系, 而只是反映了你的数据结构, 没有表明到底它们和我们的应用有何关系.
我们对这些变化和它们在可维护性方面的长期回报感到兴奋。我们也认为它们会导致可共享的,独立的库 - 整个社区可以在 phoenix 相关项目内部和外部使用.
如果你在升级时遇到问题, 请在 #elixir-lang 的irc 或 slack 联系我们, 我们会搞定它们.
我还要特别感谢 @wojtekmach , 多亏了他的帮助, 新的生成器得以按时完成. <3
Happy coding!
-Chris
完整的 changelog:
1.3.0-rc0 (2017-03-01)
-
增强
[Generator] 添加了新的
phx.new
,phx.new.web
,phx.new.ecto
项目生成器, 以及新的应用结构, 和对伞型应用的支持[Generator] 添加了新的
phx.gen.html
和phx.gen.json
资源生成器, 以及新的独立的 API 边界[Controller] 添加了
current_path
和current_url
来生成一个连接的路径和 url[Controller] 引入了
action_fallback
来注册一个plug, 作为控制器操作的回退[Controller] 封装了控制器中的异常, 以管理连接状态
[Channel] 添加了配置 channel 事件日志的选项
:log_join
,log_handle_in
[Channel] 当有未被处理的
handle_info/2
消息时发出警告[Channel] Channels 现在可以区分异常退出与应用重启, 允许客户端进入错误模式, 并在冷处理之后重连
[Router]
match
语句支持用特殊的:*
参数来匹配任何 http 方法[ConnTest] 添加
redirected_params/1
来返回在重定向的 url 中匹配到的具名参数
-
迭代
[Generator] 所有
phoenix.*
mix 任务都已经被新的phx.*
任务替代
-
JavaScript 客户端增强
添加了传递
encode
和decode
函数给 socket 构造器的能力, 使得可以对输入和输出的消息进行编码和解码.检测客户端上的心跳超时, 以便在出现异常的连接丢失时更快地告知 socket 错误
添加对 AMD/RequireJS 的支持
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。