-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgetting_started.htm
310 lines (265 loc) · 13.6 KB
/
getting_started.htm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="generator" content="Bootply" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Pomona - Getting started
</title>
<link href="content/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="content/prism.css" rel="stylesheet" type="text/css" />
<link href="content/theme.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
<link rel="apple-touch-icon" href="/bootstrap/img/apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="72x72" href="/bootstrap/img/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="114x114" href="/bootstrap/img/apple-touch-icon-114x114.png">
<!-- CSS code from Bootply.com editor -->
<link href="content/affix.css" rel="stylesheet" type="text/css" />
</head>
<!-- HTML code from Bootply.com editor -->
<body>
<a href="https://github.com/Pomona/Pomona"><img style="z-index: 5000; position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/e7bbb0521b397edbd5fe43e7f760759336b5e05f/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677265656e5f3030373230302e706e67"
alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png"></a>
<nav class="navbar navbar-default navbar-fixed-top" role="banner">
<div class="container">
<div class="navbar-header">
<a href="index.htm" class="navbar-brand">Pomona</a>
</div>
<nav class="collapse navbar-collapse" role="navigation">
<ul class="nav navbar-nav pull-right">
<li>
<a href="https://ci.appveyor.com/project/Pomona/pomona/branch/master"><img src="https://camo.githubusercontent.com/292475f55ea801049dca2b513810703735ccebce/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f766a33637734396e34393975363034362f6272616e63682f6d61737465723f7376673d74727565"
alt="Build Status" data-canonical-src="https://ci.appveyor.com/api/projects/status/vj3cw49n499u6046/branch/master?svg=true" style="max-width:100%;"></a>
</li>
<li>
<a href="https://travis-ci.org/Pomona/Pomona"><img src="https://camo.githubusercontent.com/b95255081c0290893d299b926d4bd29dca156ffd/68747470733a2f2f7472617669732d63692e6f72672f506f6d6f6e612f506f6d6f6e612e7376673f6272616e63683d6d6173746572" alt="Build Status" data-canonical-src="https://travis-ci.org/Pomona/Pomona.svg?branch=master"
style="max-width:100%;"></a>
</li>
<li>
<a href="https://gitter.im/Pomona/Pomona?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://camo.githubusercontent.com/da2edb525cde1455a622c58c0effc3a90b9a181c/68747470733a2f2f6261646765732e6769747465722e696d2f4a6f696e253230436861742e737667" alt="Join the chat at https://gitter.im/Pomona/Pomona" data-canonical-src="https://badges.gitter.im/Join%20Chat.svg"
style="max-width:100%;"></a>
</li>
<li><a href="https://www.nuget.org/packages/Pomona/"><img src="https://img.shields.io/nuget/v/Pomona.svg" alt="Nuget package" /></a></li>
<li><a href="index.htm" title="Pomona">Previous</a></li>
<li><a href="configuration/index.htm" title="Configuration and bootstrapping">Next</a></li>
</ul>
<div class="navbar-form navbar-left" role="search">
<div class="form-group">
<input id="search" type="search" class="form-control" placeholder="Search">
</div>
</div>
</nav>
</div>
</nav>
<div class="container">
<nav class="navbar">
<ol class="breadcrumb"><li><a href="index.htm">Pomona</a></li><li class="active">Getting started</li></ol>
</nav>
</div>
<!--main-->
<div class="container">
<div class="row">
<!--left-->
<div class="col-md-3" id="leftCol">
<ul class="nav nav-stacked affix" id="sidebar">
<li>
<h3><img src="/content/images/pomona-icon-210.png" width="210" height="210" alt="Pomona " /></h3></li>
<li>
<h3 class="no-margin">Next</h3>
<p><a href="configuration/index.htm">Configuration and bootstrapping</a></p></li>
<li>
<h3 class="no-margin">Previous</h3><a href="index.htm">Pomona</a></p></li>
</ul>
</div>
<!--/left-->
<!--right-->
<div class="col-md-9">
<h1>Getting started <a href="https://github.com/Pomona/Pomona/blob/develop/documentation/getting_started.md" class="text-muted small pull-right fa fa-github" style="margin-top: 10px"> Edit on GitHub</a></h1>
<hr />
<div id="main-pane">
<!--Title:Getting started-->
<!--Url:getting_started-->
<p>Here we will guide you through the steps needed to create a very basic Pomona
service.</p>
<p>This example is also available in the Pomona repository in the
<code>samples/Pomona.Samples.DustyBoxes1</code> folder of the
<a href="https://github.com/Pomona/Pomona">Pomona source</a>.</p>
<h2>Installing</h2>
<p>We start by creating a new C# console project and install the <a href="http://www.nuget.org/packages/Pomona/">Pomona NuGet package</a> from the standard NuGet feed.</p>
<pre><code>PM> Install-Package Pomona
</code></pre>
<p><em>Note: We make a command line project so we can run this as a self-hosted Nancy host. In a real life example we would probably use another type of project.</em></p>
<h3>The domain model</h3>
<p>Now that we have a empty project we need some domain model to expose.</p>
<pre><code class="language-csharp">
public class GameConsole
{
public string Id { get; set; }
public string Name { get; set; }
}
</code></pre>
<p><em>Every resource must have an id, which will be used as part of the URL.</em></p>
<h3>Setting up a module</h3>
<p>Then we need to create a module, which represents the endpoint of our service.</p>
<pre><code class="language-csharp">
[PomonaConfiguration(typeof(DustyConfiguration))]
public class DustyModule : PomonaModule
{
}
</code></pre>
<p>Additionally we need a corresponding configuration class.</p>
<pre><code class="language-csharp">
public class DustyConfiguration : PomonaConfigurationBase
{
public override IEnumerable<object> FluentRuleObjects => new object[] { new DustyRules() };
public override IEnumerable<Type> SourceTypes => new[] { typeof(GameConsole) };
public class DustyRules
{
public void Map(ITypeMappingConfigurator<GameConsole> gameConsole)
{
gameConsole.HandledBy<GameConsoleHandler>();
}
}
}
</code></pre>
<p>The configuration above have two properties overridden.</p>
<ul>
<li><code>FluentRuleObjects</code> returns a list containing one rule object <code>DustyRules</code>,
which will be scanned for mapping rules.</li>
<li><code>SourceTypes</code> returns a list of the domain objects to be mapped.</li>
</ul>
<h3>Handling resource requests</h3>
<p>In the <code>Map</code> method of the <code>DustyRules</code> we defined that <code>GameConsoleHandler</code> will
handle requests for the <code>GameConsole</code> resource.</p>
<p>This is a handler class, which will handle HTTP actions for one or more resources.
We can now implement <code>GameConsoleHandler</code>, like this:</p>
<pre><code class="language-csharp">
public class GameConsoleHandler
{
public IQueryable<GameConsole> Query()
{
return
new[]
{
new GameConsole() { Id = "a2600", Name = "Atari 2600" },
new GameConsole() { Id = "gameboy", Name = "Game Boy" },
new GameConsole() { Id = "nes", Name = "Nintendo Entertainment System" },
}.AsQueryable();
}
}
</code></pre>
<p>For exposing a read-only collection of resources we just need to define one method
returning an <code>IQueryable<GameConsole></code>.</p>
<p>Usually you would proabably use a LINQ provider here, like the one in <a href="http://nhibernate.info/">NHibernate</a> or <a href="http://www.asp.net/entity-framework">Entity Framework</a>. But for now we'll just use an in-memory array.</p>
<h3>Running the service</h3>
<p>At this point our project should contain the following classes:</p>
<ul>
<li><code>GameConsole</code> - Our domain object</li>
<li><code>GameConsoleHandler</code> - Handler for <code>GameConsole</code></li>
<li><code>DustyConfiguration</code> - Configuration for Pomona module</li>
<li><code>DustyModule</code> - The Pomona module</li>
<li><code>Program</code> - The console app startup class</li>
</ul>
<p>As mentioned earlier we will be using Nancy self host for this example. For this
the package <a href="http://www.nuget.org/packages/Nancy.Hosting.Self">Nancy.Hosting.Self</a>
must be installed from the NuGet gallery.</p>
<pre><code>PM> Install-Package Nancy.Hosting.Self
</code></pre>
<p>We also need to modify our <code>Progam.cs</code> file to actually bootstrap and fire up
a local http server.</p>
<pre><code class="language-csharp">
class Program
{
static void Main(string[] args)
{
var baseUri = new Uri("http://localhost:1337");
var nancyHost =
new NancyHost(new HostConfiguration()
{
// To show annoying UAC dialog in windows when not running as admin
UrlReservations = new UrlReservations() { CreateAutomatically = true }
}, baseUri);
nancyHost.Start();
// Automatically launch web browser
Process.Start(baseUri.ToString());
Console.WriteLine($"Starting server on {baseUri}, press enter to stop..");
Console.ReadLine();
nancyHost.Stop();
}
}
</code></pre>
<p>Now our example should be able to compile, run and be explored at <a href="http://localhost:1337">http://localhost:1337</a>.</p>
<pre><code class="language-git">$ curl http://localhost:1337 -H "Accept: application/json"
{
"game-consoles": "http://localhost:1337/game-consoles"
}
</code></pre>
<pre><code class="language-git">C:\>curl http://localhost:1337/game-consoles -H "Accept: application/json"
{
"_type": "__result__",
"totalCount": -1,
"items": [
{
"_uri": "http://localhost:1337/game-consoles/a2600",
"id": "a2600",
"name": "Atari 2600"
},
{
"_uri": "http://localhost:1337/game-consoles/gameboy",
"id": "gameboy",
"name": "Game Boy"
},
{
"_uri": "http://localhost:1337/game-consoles/nes",
"id": "nes",
"name": "Nintendo Entertainment System"
}
],
"skip": 0,
"previous": null,
"next": null
}
</code></pre>
<p>And there you have it, <strong>congratulations</strong>, you have just completed our little
tutorial. Read the following chapters of the documentation for further experimentation,</p>
</div>
<hr />
<nav>
<span>
<strong>Previous: </strong><a href="index.htm">Pomona</a>
</span>
<span class="pull-right">
<strong>Next: </strong><a href="configuration/index.htm">Configuration and bootstrapping</a>
</span>
</nav>
</div>
<!--/right-->
</div>
<!--/row-->
<footer><p><small><i>Documentation created using <a href="https://storyteller.github.io/">Storyteller</a></i></small></p></footer>
</div>
<!--/container-->
</body>
<foot>
<script type='text/javascript' src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type='text/javascript' src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="content/prism.js"></script>
<script type="text/javascript" src="content/sidebar.js"></script>
<script type="text/javascript" src="content/affix.js"></script>
<script>
$('#search').keyup(function(e) {
if (e.keyCode == 13) {
var search = $('#search').val();
var url = 'https://www.google.com/#q=site:pomona.io ' + search;
url = encodeURI(url);
//alert(url);
window.location.href = url;
e.stopPropagation();
if (e.cancelBubble != null) e.cancelBubble = true;
return false;
}
});
</script>
</foot>
</html>