elixir 规格
by Ben Church
通过本教堂
如何用Elixir,Phoenix和Mnesia编写超快速链接缩短器 (How to write a super fast link shortener with Elixir, Phoenix, and Mnesia)
Let's start this month’s tutorial with two statements that are going to get me in trouble:
让我们从本月的教程开始,其中有两条陈述会给我带来麻烦:
- Elixir is the most productive language out there. Elixir是世界上生产力最高的语言。
- Bit.ly charges way much for their paid plan Bit.ly为他们的付费计划收取了很多费用
Elixir, the Phoenix framework, and the Erlang VM allows us to make production ready systems fast, easily, and with very few moving parts. At this point, you can see where we’re going with this. Let’s use what comes out of the box with Elixir to create a link shortener and prevent a $500 monthly bill.
Elixir,Phoenix框架和Erlang VM使我们能够快速,轻松且几乎没有活动部件地制造可投入生产的系统。 在这一点上,您可以看到我们的发展方向。 让我们使用Elixir开箱即用的产品来创建链接缩短器并防止每月500美元的账单。
Let’s dive in!
让我们潜入吧!
最初设定 (Initial Setup)
在你开始前 (Before you start)
Please make sure you have the following:
请确保您具有以下条件:
创建一个新的Phoenix项目 (Create a new Phoenix Project)
The first thing to do as always is to have Phoenix create the skeleton of the project. For this demo, we won't have a “frontend” so we can tell the initializer to leave those out.
与往常一样,第一件事是让Phoenix创建项目的框架。 对于此演示,我们将没有“前端”,因此我们可以告诉初始化程序将其忽略。
In your terminal type:
在您的终端中输入:
mix phx.new shorten_api --no-html --no-brunch
更新你的依赖 (Update your dependencies)
Next, we're going to add a few dependencies to mix.exs
. Go ahead and update the deps/0
function in that file to look like this:
接下来,我们将向mix.exs
添加一些依赖mix.exs
。 继续更新该文件中的deps/0
函数,如下所示:
逻辑! (Logic!)
Ok basic set up out of the way. That means we’re into setting up the logic that will:
确定基本设置。 这意味着我们正在建立将要执行的逻辑:
- Allow us to save URLs 允许我们保存网址
Reference these URLs by a unique HashId (ex.
abc123
)通过唯一的HashId(例如
abc123
)引用这些URL。Navigate to
/abc123
and it redirects to the URL that it references导航到
/abc123
,然后重定向到它引用的URL
First up, creating a way to store these links.
首先,创建一种存储这些链接的方法。
创建一种存储这些链接的方法 (Creating a way to store these links)
Let's use Phoenix’s built-in generators to do this for us. In your terminal run:
让我们使用Phoenix的内置生成器为我们完成此任务。 在您的终端运行中:
mix phx.gen.json Links Link links hash:string:unique url:string:unique
mix phx.gen.json Links Link links hash:string:unique url:string:unique
This will create the
这将创建
Links
contextLinks
上下文Link
modelLink
模型Link
controllerLink
控制器- Database migration 数据库迁移
That’s honestly the end of that step. It will ask you to put a few lines in your router.ex
file but for now, you can skip that if you want as we will touch on it later. Let's move onto how we can modify what was created above to automatically create the id’s we will use to reference these links.
老实说,那是结束的一步。 它将要求您在router.ex
文件中添加几行,但是现在,如果需要,您可以跳过该行,因为稍后我们会进行介绍。 让我们继续介绍如何修改上面创建的内容以自动创建ID,我们将使用这些ID来引用这些链接。
在链接创建时自动生成HashId (Autogenerate the HashId on Link creation)
By default in these systems, models are given an id
column in the database that is a number, unique and auto increments: 1, 2, 3 and so on. In our system we want the id
to be a:
在这些系统中,默认情况下,在数据库中为模型提供一个id
列,该列是一个数字,唯一且自动递增:1、2、3,依此类推。 在我们的系统中,我们希望id
为:
- Short 短
- Unique 独特
- String 串
- That auto-generates. 会自动生成。
Ecto makes this really easy.
Ecto使此操作非常容易。
The first thing to do is make a custom Ecto Type which will handle all of this for us. Create a new file shorten_api/ecto/hash_id.ex
and populate it as follows:
首先要做的是创建一个自定义的Ecto类型,它将为我们处理所有这一切。 创建一个新文件shorten_api/ecto/hash_id.ex
并按如下所示进行填充:
What we did above is essentially create a new type that can be used the same way we define a field as a String
or an Integer
. Now we can define a field as a HashId
.
上面我们所做的基本上是创建一个新类型,该新类型可以与将字段定义为String
或Integer
。 现在我们可以将字段定义为HashId
。
You can learn more about this in the Ecto documentation.
So let's do just that and update shorten_api/links/link.ex
to use a HashId
as it’s a primary key instead of an Integer
:
因此,让我们这样做,并更新shorten_api/links/link.ex
以使用HashId
因为它是主键而不是Integer
:
更新迁移 (Update the migration)
Now that the HashId
is setup in our code, we want to update the migration to set up the database to reflect what's happening in our model file. You should have a file in your project that ends with _create_links.exs
. Find it, open it and modify it to resemble the below code:
现在,我们的代码中已经设置了HashId
,我们想要更新迁移以设置数据库以反映模型文件中发生的事情。 您的项目中应该有一个以_create_links.exs
结尾的文件。 找到它,将其打开并修改为类似于以下代码:
Alright, that's the majority of our plumbing steps, now we’re going to jump into the core logic of this whole project.
好吧,这是我们大部分的探索步骤,现在我们将跳入整个项目的核心逻辑。
从ID重定向到URL (Redirect from an Id to a URL)
First, we need a function in our controller that
首先,我们需要在控制器中使用一个函数
Takes an
Id
of aLink
取得
Link
Id
Looks up the
Link
查找
Link
Redirects to the
URL
attached to thatLink
重定向到该
Link
所附的URL
To do this, let's add a new function to our link controller found here: shorten_api_web/controllers/link_controller.ex
为此,让我们向此处的链接控制器添加一个新函数: shorten_api_web/controllers/link_controller.ex
将所有内容挂接到我们的路由器 (Hook it all up to our router)
Now that we have this new controller function, the only thing left is to hook it up. Update the router.ex
file to reflect the following:
现在我们有了这个新的控制器功能,剩下的就是将其连接起来。 更新router.ex
文件以反映以下内容:
Note: we will also be adding the routes to
mix phx.gen
suggested earlier注意:我们还将添加路由,以
mix phx.gen
建议的mix phx.gen
TADA! ? (TADA! ?)
At this point, you should be able to run the project with mix phx.server
and have everything function as expected! However, we’re not stopping here.
此时,您应该可以使用mix phx.server
运行项目, mix phx.server
所有功能都按预期运行! 但是,我们不止于此。
秘制酱 (Secret sauce)
Because link shorteners sit between a user and the actual content, it is crucial that these systems are fast. While Elixir is already fast, the main lag time in this process comes from our database. It takes time to look up the Link attached to an id.
由于链接缩短器位于用户和实际内容之间,因此这些系统的速度至关重要。 尽管Elixir已经快了,但是此过程中的主要滞后时间来自我们的数据库。 查找附加到ID的链接需要花费时间。
To speed this up, link shorteners will often opt to use an in-memory datastore like Redis as opposed to an on-disk database like Postgres (which Phoenix sets us up with by default). Thankfully because Elixir is built on top of the Erlang VM, we already have an in-memory datastore built in: Mnesia!
为了加快速度,链接缩短器通常会选择使用内存数据存储(如Redis),而不是磁盘数据库(如Postgres)(Phoenix默认将其设置为我们)。 值得庆幸的是,由于Elixir是在Erlang VM之上构建的,因此我们已经有一个内置的内存数据存储区:Mnesia!
In the next section, we’re going to alter our configuration to use Mnesia instead of Postgres.
在下一节中,我们将更改配置以使用Mnesia代替Postgres。
从Postgres交换到Mnesia (Swapping from Postgres to Mnesia)
This process is actually very simple. First update config.exs
as shown:
这个过程实际上非常简单。 首先更新config.exs
,如下所示:
创建您的Mnesia数据库 (Create your Mnesia database)
Then create the location where Mnesia will back data up to and initialize the database through Ecto:
然后创建Mnesia将数据备份到的位置,并通过Ecto初始化数据库:
mkdir priv/datamkdir priv/data/mnesiamix ecto.createmix ecto.migrate
Boom done! You’re now using an In-Memory database to hold our Link information. Wasn’t that easy?
繁荣! 您现在正在使用内存数据库来保存我们的链接信息。 那不是那么容易吗?
踢开 (Kick it off)
You now can
您现在可以
- start the project (again for many of you): 重新启动项目(对许多人来说也是这样):
mix phx.server
mix phx.server
2. Create a shortened link via curl
:
2.通过curl
创建一个缩短的链接:
curl --request POST \ --url http://localhost:4000/api/links/ \ --header 'content-type: application/json' \ --data '{ "link": { "url": "https://twitter.com/bnchrch" }}'
3. Take the hash
returned in the response
3.取回响应中返回的hash
{“data”:{“url”:”https://twitter.com/bnchrch","hash":"7cJY_ckq"}}
{“data”:{“url”:” https://twitter.com/bnchrch ","hash":"7cJY_ckq"}}
4. And be redirected appropriately when you go to localhost:4000/{hash}
:
4.并在进入localhost:4000/{hash}
时进行适当的重定向:
结语 (Wrap up)
Amazing how easy it was with all these tools to create a fast, easy to maintain and simple to extend link shortener. A lot of the credit here can go to the BEAM (Erlang VM), Jose Valim (creator of Elixir), and Chris McCord (creator of Phoenix). The rest of the praise goes to how simple the idea of a link shortener is, in no way justifying a $500 per month introductory price tag. Still looking at you Bit.ly.
使用所有这些工具创建快速,易于维护和易于扩展的链接缩短器多么容易。 BEAM(Erlang VM),Jose Valim(Elixir的创建者)和Chris McCord(Phoenix的创建者)可以得到很多荣誉。 其余的称赞在于链接缩短器的想法有多么简单,决不能证明每月500美元的入门价格标签是合理的。 还在看着你Bit.ly。
?这是开源的! 您可以在Github上找到它 (? This is open source! you can find it here on Github)
❤️我只写关于编程和远程工作的文章。 如果您在Twitter上关注我,我不会浪费您的时间。 (❤️ I only write about programming and remote work. If you follow me on Twitter I won’t waste your time.)
elixir 规格