服务器客户端证书模板_服务器端模板和以API为中心的开发

news/2024/7/10 2:28:22 标签: python, java, javascript, html, vue
htmledit_views">

服务器客户端证书模板

We’re here to talk about the rise of the API-focused application, and how it interacts with templates for rendering HTML for web browsers. The simple point I hope to make is: you don’t necessarily need to use all client side templates in order to write an effective API-centric web application.

我们在这里谈论以API为中心的应用程序的兴起,以及它如何与模板交互以为Web浏览器呈现HTML。 我希望说明的简单点是:不一定需要使用所有客户端模板来编写有效的以API为中心的Web应用程序。

I’ll do this by illustrating a simple web application, with a single API-oriented method (that is, returns JSON-oriented data), where the way it’s rendered and the style of template in use is entirely a matter of declarative configuration. Rendering of full pages as well as Ajax delivered “fragments” are covered using both server- and client-side rendering approaches.

我将通过使用一个单一的面向API的方法(即返回面向JSON的数据)来说明一个简单的Web应用程序,该方法的呈现方式和所用模板的样式完全是声明性配置。 使用服务器端和客户端渲染方法都可以覆盖整页的渲染以及Ajax交付的“片段”。

以API为中心的开发 (API Centric Development)

Most dynamic web applications we write today have the requirement that they provide APIs – that is, methods which return pure data for the consumption by a wide variety of clients. The trend here is towards organizing web applications from the start to act like APIs. In a nutshell, it means we are moving away from mode of data models injected into templates:

我们今天编写的大多数动态Web应用程序都要求它们提供API –即,返回纯数据以供各种客户端使用的方法。 这里的趋势是从一开始就组织Web应用程序以使其像API。 简而言之,这意味着我们正在远离注入模板的数据模型的模式:

def def get_balanceget_balance (( requestrequest ):
    ):
    balance balance = = BankBalanceBankBalance (
        (
        amount amount = = AmountAmount (( 1000010000 , , currencycurrency == "euro""euro" ),
        ),
        as_of_date as_of_date = = datetimedatetime .. datetimedatetime (( 20122012 , , 66 , , 1414 , , 1212 , , 00 , , 00 )
    )
    )
    )
    return return render_templaterender_template (( "balance.html""balance.html" , , balancebalance == balancebalance )
)

and instead towards returning JSON-compatible data structures, with the “view” being decided somewhere else:

而不是返回JSON兼容的数据结构,而在其他地方确定“视图”:

This is a fine trend, allowing us to make a clearer line between server side concepts and rendering concepts, and giving us an API-centric view of our data from day one.

这是一个很好的趋势,它使我们可以在服务器端概念和呈现概念之间建立更清晰的界限,并从一开始就为我们提供以API为中心的数据视图。

范本 (Templates)

There’s a misunderstanding circulating about API-centric development which says that we have to use client side templates:

关于以API为中心的开发存在一种误解,这表明我们必须使用客户端模板:

API-centric development. If you take a client-side rendering approach, odds are the server side of your web application is going to look more like an API than it would if you were doing entirely server-side rendering. And if/when you have plans to release an API, you’d probably already be 90% of the way there. (http://openmymind.net/2012/5/30/Client-Side-vs-Server-Side-Rendering/#comment-544974348)

以API为中心的开发。 如果您采用客户端渲染方法,则与完全执行服务器端渲染相比,Web应用程序的服务器端看起来更像是API。 而且,如果/当您计划发布API时,您可能已经完成了90%的工作。 ( http://openmymind.net/2012/5/30/Client-Side-vs-Server-Side-Rendering/#comment-544974348 )

and:

和:

Lastly, another issue i can see, assuming you develop using MVC. You need to have the view, model and controller very tightly coupled to make his way work. The controller needs to know how the view works to create html that can slot right in. It’s easier if the controller only has to pass data, not layout information. (http://www.reddit.com/r/programming/comments/ufyf3/clientside_vs_serverside_rendering/c4v5vjb)

最后,假设您使用MVC开发,我可以看到另一个问题。 您需要使视图,模型和控制器紧密结合,以使其工作正常。 控制器需要知道视图如何创建可以直接插入的html。如果控制器只需要传递数据,而不传递布局信息,则会更加容易。 ( http://www.reddit.com/r/programming/comments/ufyf3/clientside_vs_serverside_rendering/c4v5vjb )

This second quote is specific to the approach of delivering rendered HTML in an ajax response, to be directly rendered into a DOM element, which we will also demonstrate here. How the “model” is more tightly coupled to anything when you have a server side vs client side template, I have absolutely no idea.

第二个引号特定于在ajax响应中传递呈现HTML的方法,该方法将直接呈现为DOM元素,我们还将在此处进行演示。 当您拥有服务器端和客户端模板时,“模型”如何更紧密地与任何事物耦合,我绝对不知道。

Why might we want to stick with server side templates? As a Python developer, in my view the main reason is that they are still a lot easier to develop with, assuming we aren’t developing our server in Javascript as well. Consider if our bank account balance needed locale-specific number, currency and date formatting, and also needed to convert the timestamp from UTC into a preferred timezone. A server side approach allows us to easily inject more functionality into our template as part of its standard environment for all render calls, such as something like this:

为什么我们要坚持使用服务器端模板? 在我看来,作为一名Python开发人员,主要原因是假设我们也没有使用Javascript开发服务器时,使用它们进行开发仍然要容易得多。 考虑一下我们的银行帐户余额是否需要特定于区域设置的数字,货币和日期格式,是否还需要将时间戳从UTC转换为首选时区。 服务器端方法使我们能够轻松地向模板中添加更多功能,作为其标准环境中所有渲染调用的一部分,例如:

def def render_templaterender_template (( requestrequest , , templatetemplate , , **** template_nstemplate_ns ):
    ):
    number_formatter number_formatter = = number_formatternumber_formatter (( requestrequest .. useruser .. preferred_localepreferred_locale )
    )
    template_nstemplate_ns [[ 'currency_format''currency_format' ] ] = = currency_formattercurrency_formatter (( number_formatternumber_formatter )
    )
    template_nstemplate_ns [[ 'date_format''date_format' ] ] = = date_formatterdate_formatter (
                                (
                                requestrequest .. useruser .. preferred_timezonepreferred_timezone ,
                                ,
                                requestrequest .. useruser .. preferred_date_formatpreferred_date_format )
    )
    return return lookuplookup .. get_templateget_template (( templatetemplate )) .. renderrender (( **** template_nstemplate_ns )
)

The template can, if it needs to, call upon these methods like this:

模板可以根据需要调用以下方法:

With a client side template, we have to implement all of currency_formatter, number_formatter, date_formatter in Javascript. These methods may need to respond to business-specific inputs, such as specific user preferences or other rules, that also need to be pushed up to the client. All the additional Javascript logic we’re pushing out to the client brings forth the need for it to be unit tested, which so far means we need to add significant complexity to the testing environment by running a Javascript engine like node.js or something else in order to test all this functionality. Remember, we’re not already using node.js to do the whole thing. If we were, then yes everything is different, but I wasn’t planning on abandoning Python for web development just yet.

使用客户端模板,我们必须在Javascript中实现currency_formatternumber_formatterdate_formatter的全部。 这些方法可能需要响应特定于业务的输入,例如特定的用户首选项或其他规则,这些输入也需要推送给客户端。 我们要提供给客户端的所有其他Javascript逻辑带来了对其进行单元测试的需求,这意味着到目前为止,我们需要通过运行诸如node.js之类的Javascript引擎或其他工具来增加测试环境的复杂性为了测试所有这些功能。 记住,我们还没有使用node.js来完成整个工作。 如果是的话,那么是的,一切都不同了,但是我还没有计划放弃Python进行Web开发。

Some folks might argue that elements like date conversion and number formatting should still remain on the server, but just be applied by the API to the data being returned directly. To me, this is specifically the worst thing you can do – it basically means that the client side approach is forcing you to move presentation-level concepts directly into your API’s data format. Almost immediately, you’ll find yourself having to inject HTML entities for currency symbols and other browser-specific markup into this data, at the very least complicating your API with presentational concerns and in the worst case pretty much ruining the purity of your API data. While the examples here may be a little contrived, you can be sure that more intricate cases come up in practice that present an ongoing stream of hard decisions between complicating/polluting server-generated API data with presentation concepts versus building a much heavier client than initially seemed necessary.

有些人可能会争辩说日期转换和数字格式之类的元素仍应保留在服务器上,而仅由API应用于直接返回的数据。 对我来说,这是最糟糕的事情-它基本上意味着客户端方法迫使您将表示级别的概念直接移到API的数据格式中。 几乎立即,您会发现自己必须将用于货币符号和其他特定于浏览器的标记HTML实体注入到该数据中,至少使您的API出现表示方面的问题变得非常复杂,在最坏的情况下,这几乎破坏了API数据的纯度。 尽管此处的示例有些人为设计,但您可以肯定的是,在实践中会出现更多复杂的案例,这些案例在呈现/污染服务器生成的API数据(带有演示概念)与构建比最初重得多的客户端之间呈现出一系列艰难的决定。似乎是必要的。

Also, what about performance? Don’t client side/server side templates perform/scale/respond worse/better? My position here is “if we’re just starting out, then who knows, who cares”. If I’ve built an application and I’ve observed that its responsiveness or scalability would benefit from some areas switching to client side rendering, then that’s an optimization that can be made later. We’ve seen big sites like LinkedIn switch from server to client side rendering, and Twitter switch from client to server side rendering, both in the name of “performance”! Who knows! Overall, I don’t think the difference between pushing out json strings versus HTML fragments is something that warrants concern up front, until the application is more fully formed and specific issues can addressed as needed.

另外,性能如何? 客户端/服务器端模板不执行/缩放/响应更差/更好吗? 我在这里的立场是“如果我们只是开始,那么谁知道,谁在乎”。 如果我已经构建了一个应用程序,并且观察到它的响应性或可伸缩性将从某些区域切换到客户端呈现中受益,那么这是可以在以后进行的优化。 我们已经看到像LinkedIn这样的大型网站都以“性能”的名义从服务器转换为客户端渲染 ,而Twitter从客户端转换为服务器渲染 ! 谁知道! 总的来说,我认为推出json字符串与HTML片段之间的区别并不需要引起人们的关注,直到应用程序更加完整并可以根据需要解决特定问题为止。

另类 (The Alternative)

Implementing a larger client-side application than we might have originally preferred is all doable of course, but given the additional steps of building a bootstrap system for a pure client-side approach, reimplementing lots of Python functionality, in some cases significant tasks such as timezone conversion, into Javascript, and figuring out how to unit test it all, is a lot of trouble for something that is pretty much effortless in a server side system – must we go all client-side in order to be API centric?

当然,可以实现比我们最初更喜欢的更大的客户端应用程序,但是考虑到为纯客户端方法构建引导系统的额外步骤,需要重新实现许多Python功能,在某些情况下,例如某些重要任务将时区转换为Javascript,并弄清楚如何对其进行全部测试,这对于在服务器端系统中几乎不费吹灰之力的工作来说会带来很多麻烦-我们必须以客户端为中心以API为中心吗?

Of course not!

当然不是!

The example I’ve produced illustrates a single, fake API method that produces a grid of random integers:

我产生的示例说明了一个伪造的API方法,该方法会生成随机整数的网格:

@view_config@view_config (( route_nameroute_name == 'api_ajax''api_ajax' , , rendererrenderer == 'json''json' )
)
def def apiapi (( requestrequest ):
    ):
    return return [
        [
        [[ "" %0.2d%0.2d " " % % randomrandom .. randintrandint (( 11 , , 9999 )  )  for for col col in in xrangexrange (( 1010 )]
        )]
        for for row row in in xrangexrange (( 1010 )
    )
    ]
]

and delivers it in four ways – two use server side rendering, two use client side rendering. Only one client template and one server side template is used, and there is only one API call, which internally knows nothing whatsoever about how it is displayed. Basically, the design of our server component is un-impacted by what style of rendering we use, save for different routing declarations which we’ll see later.

并以四种方式交付它-两种使用服务器端渲染,两种使用客户端渲染。 仅使用一个客户端模板和一个服务器端模板,并且只有一个 API调用,该调用在内部对其显示方式一无所知。 基本上,我们服务器组件的设计不受所用呈现方式的影响,除了不同的路由声明外,我们将在后面看到。

For client side rendering of this data, we’ll use a handlebars.js template:

为了在客户端呈现此数据,我们将使用handlebars.js模板:

and for server side rendering, we’ll use a Mako template:

对于服务器端渲染,我们将使用Mako模板:

<%<% inherit inherit file=file= "layout.mako""layout.mako" />/> 



${${ display_apidisplay_api (( TrueTrue )) }} 



<%<% def def name=name= "display_api(inline=False)""display_api(inline=False)" >> 

    <p>
    <p>
        API data -
                API data -
        % % if if inlineinline :: 

            Displayed inline within a server-rendered page
                    Displayed inline within a server-rendered page
        % % elseelse :: 

            Displayed via server-rendered ajax call
                    Displayed via server-rendered ajax call
        %%  endif endif 

    </p>
    </p>
    <table>
            <table>
        % % for for row row in in datadata :: 

            <tr>
                            <tr>
                % % for for col col in in rowrow :: 

                    <td>                    <td> ${${ colcol }} </td>
                </td>
                %%  endfor endfor 

            </tr>
                    </tr>
        %%  endfor endfor 

    </table>
    </table>
</%</% defdef >> 

The Mako template is using a <%def> to provide indirection between the rendering of the full page, and the rendering of the API data. This is not a requirement, but is here because we’ll be illustrating also how to dual purpose a single Mako template such that part of it can be used for a traditional full page render as well as for an ajax-delivered HTML fragment, with no duplication. It’s essentially a Pyramid port of the same technique I illustrated with Pylons four years ago in my post Ajax the Mako Way, which appears to be somewhat forgotten. Among other things, Pyramid’s Mako renderer does not appear integrate the capability to call upon page defs directly, even though I had successfully lobbied to get the critical render_def() into its predecessor Pylons. Here, I’ve implemented my own Mako renderer for Pyramid.

Mako模板使用<%def>在整个页面的呈现和API数据的呈现之间提供间接。 这不是必需的,而是在这里,因为我们还将说明如何双重使用单个Mako模板,以便其中的一部分可用于传统的整页渲染以及Ajax交付HTML片段,没有重复。 从本质上讲,它是一个金字塔端口,与四年前我在Ajax的《 Mako Way》一文中与Pylons所阐述的技术相同,这似乎有些被人遗忘了。 除其他事项外,Pyramid的Mako渲染器似乎没有集成直接调用页面defs的功能,即使我已经成功游说将关键的render_def()放入其先前的Pylons中。 在这里,我为金字塔实现了自己的Mako渲染器。

Key here is that we are separating the concept of how the API interface is constructed, versus what the server actually produces. Above, note we’re using the Pyramid “json” renderer for our API data. Note the term “renderer”. Interpreting our API method as a JSON API, as a call to a specific client-side template plus JSON API, or as a server side render or ajax call is just a matter of declaration. The way we organize our application in an API-centric fashion has nothing to do with where the rendering takes place. To illustrate four different ways of interpreting the same API method, we just need to add four different @view_config directives:

这里的关键是我们将API接口的构造概念与服务器实际产生的概念分开。 上面,请注意,我们正在使用Pyramid“ json”渲染器获取API数据。 注意术语“渲染器”。 将我们的API方法解释为JSON API,作为对特定客户端模板加上JSON API的调用,或者作为服务器端渲染或ajax调用的解释仅是声明的问题。 我们以API为中心的方式组织应用程序的方式与进行渲染的位置无关。 为了说明解释同一API方法的四种不同方式,我们只需要添加四个不同的@view_config指令:

The rendering methods here are as follows:

这里的渲染方法如下:

  • Method One, Server Via Server – The api() view method returns the data, which is received by the home.mako template, which renders the full page, and passes the data to the display_api() def within the same phase for all-at-once server side rendering.
  • Method Two, Server Via Client – A hyperlink on the page initiates an ajax call to the server’s server_ajax route, which invokes the api() view method, and returns the data directly to the display_api def present in the home.mako template. For this case, I had to create my own Pyramid Mako renderer that receives a custom syntax, where the page name and def name are separated by a pipe character.
  • Method Three, Client Via Server – Intrinsic to any client side rendered approach is that the server needs to first deliver some kind of HTML layout, as nothing more than a launching point for all the requisite html" title=java>javascript needed to start rendering the page for real. This method illustrates that, by delivering the handlebars_base.mako template which serves as the bootstrap point for any server-initiated page call that renders with a client side template. In this mode, it also embeds the data returned by api() within the <script> tags at the top of the page, and then invokes the Javascript application to render the display_api.handlebars template, providing it with the embedded data. Another approach here might be to deliver the template in one call, and to have the client invoke the api() method as a separate ajax call, though this takes two requests instead of one and also implies adding another server-side view method.
  • Method Four, Client Via Client – A hyperlink on the page illustrates how a client-rendered application can navigate to a certain view, calling upon the server only for raw data (and possibly the client side template itself, until its cached in a client-side collection). The link includes additional attributes which allow the html" title=java>javascript application to call upon the display_api.handlebars template directly, and renders it along with the data returned by calling the api() view method with the json renderer.
  • 方法一,通过服务器进行服务器 -api ()视图方法返回由home.mako模板接收的数据,该模板呈现整个页面,并将数据传递给同一阶段内的display_api() def,一次服务器端渲染。
  • 方法二,通过客户端服务器 -页面上的超链接启动对服务器的server_ajax路由的ajax调用,该调用将调用api()视图方法,并将数据直接返回到home.mako模板中存在的display_api def。 对于这种情况,我必须创建自己的Pyramid Mako渲染器,该渲染器将接收自定义语法,其中页面名称和def名称由竖线字符分隔。
  • 方法三,通过服务器客户端 –任何客户端呈现方法的内在特性是服务器需要首先提供某种HTML布局,这无非是为开始呈现页面所需的所有必需JavaScript的启动点。 此方法说明,通过传递handlebars_base.mako模板,该模板可用作使用客户端模板呈现的任何服务器启动的页面调用的引导点。 在这种模式下,它还将api()返回的数据嵌入到页面顶部的<script>标记中,然后调用Javascript应用程序来呈现display_api.handlebars模板,并向其提供嵌入的数据。 这里的另一种方法可能是在一个调用中传递模板,并让客户端将api()方法作为一个单独的ajax调用来调用,尽管这需要两个请求而不是一个请求,并且还意味着添加另一个服务器端view方法。
  • 方法四,通过客户端访问客户端 -页面上的超链接说明了客户端呈现的应用程序如何导航到某个视图,仅在服务器上调用原始数据(可能还调用了客户端模板本身,直到将其缓存在客户端中,边收集)。 该链接包含其他属性,这些属性允许html" title=java>javascript应用程序直接调用display_api.handlebars模板,并将其与通过json渲染器调用api()视图方法返回的数据一起呈现。

Credit goes to Chris Rossi for coming up with the original client-side rendering techniques that I’ve adapted here.

克里斯·罗西(Chris Rossi)提出了我在这里采用的原始客户端渲染技术,这归功于他。

A screen shot of what we’re looking at is as follows:

我们正在查看的屏幕截图如下:

Template Demo Screenshot

The demonstration here is hopefully useful not just to illustrate the server techniques I’m talking about, but also as a way to play around with client side rendering as well, including mixing and matching both server and client side rendering together. The hybrid approach is where I predict most applications will be headed.

希望这里的演示不仅对说明我正在谈论的服务器技术有用,而且还可以作为一种玩弄客户端渲染的方法,包括将服务器和客户端渲染混合并匹配在一起。 我预计大多数应用程序都将采用混合方法。

You can pull out the demo using git at https://bitbucket.org/zzzeek/client_template_demo. Enjoy !

您可以在https://bitbucket.org/zzzeek/client_template_demo上使用git提取演示。 请享用 !

翻译自: https://www.pybloggers.com/2012/06/server-side-templates-and-api-centric-development/

服务器客户端证书模板


http://www.niftyadmin.cn/n/983203.html

相关文章

基于HTTP的直播点播HLS

HLS&#xff08;HTTP Live Streaming&#xff09; 是Apple在2009年发布的&#xff0c;可以通过普通的web服务器进行分发的新型流媒体协议。苹果官方对于视频直播服务提出了 HLS 解决方案&#xff0c;该方案主要适用范围在于&#xff1a;使用 iPhone 、iPod touch、 iPad 以及 A…

TDengine 在蓝深远望电机物联网监测预警与预测性维护平台中的应用

作者&#xff1a;李凯 蓝深远望 小 T 导读&#xff1a;蓝深远望致力于服务政府及大型国有企事业单位的数字化转型&#xff0c;结合大数据、数字孪生、区块链、网络安全等核心技术&#xff0c;为政府运行、社会服务、城市管理、公共安全、基层治理等领域&#xff0c;提供智能场景…

不登录QQ,恢复QQ聊天中的语音到电脑上,并导出为MP3

之前发过一篇文章&#xff0c;专门讲了如何恢复导出微信的语音到电脑上&#xff0c;并转为MP3&#xff0c;用来方便整理的&#xff0c;本篇文章专门讲如何恢复QQ的语音&#xff0c;并导出到电脑上&#xff0c;保存为MP3。 QQ和微信一样&#xff0c;聊天记录中使用的语音使用的…

新年伊始,涛思数据公布TDengine2021年度最佳案例奖

导语&#xff1a;在2022年伊始&#xff0c;恰逢辛丑牛年除夕夜即将到来之际&#xff0c;为感恩客户的支持、回馈市场的关注&#xff0c;涛思数据于2022年1月20日正式公布TDengine2021年度最佳案例奖。本次奖项的评选以各参评企业的业务落地和客户案例作为评选材料&#xff0c;从…

Hive小文件合并

Hive的后端存储是HDFS&#xff0c;它对大文件的处理是非常高效的&#xff0c;如果合理配置文件系统的块大小&#xff0c;NameNode可以支持很大的数据量。但是在数据仓库中&#xff0c;越是上层的表其汇总程度就越高&#xff0c;数据量也就越小。而且这些表通常会按日期进行分区…

微信聊天图片视频怎么防撤回?自动备份/保存微信的聊天图片和视频(天有不撤图片视频)

本软件可以实时监测微信电脑版个人数据文件夹&#xff0c;并实时备份收到的图片和视频&#xff0c;即使对方撤回&#xff0c;也不会被删除&#xff0c;达到使对方撤回图片和视频失效的目的 在某些使用场景&#xff0c;也适用于对微信聊天的图片和视频有实时备份的需求的人&…

如何做SEO站内代码优化

如何做SEO站内代码优化seo优化工作中最基本一项是要看的懂网页代码&#xff0c;如果你不懂网页代码&#xff0c;这样的SEO就是个残废&#xff0c;这话一点不夸张&#xff0c;我们优化网页代码的时候要注意一下几点。一、空格&#xff0c;空格在网页中站15%的比例&#xff0c;空…

『TDengine2021用户故事』征文活动进入投票阶段

『TDengine2021 用户故事』 征文投票 转眼间 距离征文活动启动已经过去了一个月了&#xff01; 伴随着年关的临近 我们也正式迎来了令人期待的“全民投票”环节 到底 iPhone13 Pro 将花落谁手&#xff1f; 为期 4 天的投票结束后 谜底也将正式揭开 历时 30 天 我们收获了…