-
Notifications
You must be signed in to change notification settings - Fork 21
tutorial_01
This tutorial describes how to quickly get started with n-odata-server. In this tutorial you will learn how to
- create a loopback application
- install n-odata-server package into this application
- configure n-odata-server
- create a simple data / OData model
- run the application
- invoke some OData request against the application
To be able to follow this tutorial node.js as well as it's package manager npm must be installed on your computer. There are a lot of resources on the internet that describe this perfectly. So we will directly jump to the next step.
Cause n-odata-server is based on the amazing API framework loopback you have to install loopback first. This is done by running
npm install -g strongloop
on the command line.
To create a loopback application run
slc loopback
on the command line. Answer the questions that this program asks.
_-----_
| | ╭──────────────────────────╮
|--(o)--| │ Let's create a LoopBack │
`---------´ │ application! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? What's the name of your application? tutorial_01
? Enter name of the directory to contain the project: n_odata_server_tut_01
create n_odata_server_tut_01/
info change the working directory to n_odata_server_tut_01
? What kind of application do you have in mind? api-server (A LoopBack API server with local User auth)
? Which version of LoopBack would you like to use? 2.x
Choose api-server
as kind of application and version 2.x
. When you press enter the loopback client generates a complete program skeleton for you. At the end you should see something like this:
Next steps:
Change directory to your app
$ cd n_odata_server_tut_01
Create a model in your app
$ slc loopback:model
Compose your API, run, deploy, profile, and monitor it with Arc
$ slc arc
Run the app
$ node .
CD into your directory and have a look at the created folders and files. It should look like this.
├── client
│ └── README.md
├── node_modules
│ ├── compression
│ ├── ...
│ ├── ...
├── package.json
└── server
├── boot
│ └── root.js
├── component-config.json
├── config.json
├── datasources.json
├── middleware.json
├── middleware.production.json
├── model-config.json
└── server.js
We want to store our data in a database / datastore. Loopback supports serveral datastores.
In this tutorial we use for simplicity reasons an In-Memory-Datastore which stores it's data not only in memory
but also in a text file. So the data is available also after restarting the server.
The datastore has already been created as in-memory-only database. To enable saving data to a file we have to
add a single line to the file server/datasource.json
{
"db": {
"name": "db",
"localStorage": "",
"file": "storage/data.json",
"connector": "memory"
}
}
We add the line "file": "storage/data.json",
to the file.
After you created the datasource you have to create the data file manually. So enter the follwoing two commands.
mkdir storage
touch storage/data.json
This create the folder storage
and the file storage/data.json
Your data structure is managed as so called models in loopback. The models are mapped to tables resp. documents in the underlying database.
Lets create a simple model to manage persons / people. Our model is supposed to have only the two field firstname
and lastname
.
Enter the following command into your terminal window.
slc loopback:model
The program will ask you several questions. Just enter this data.
? Enter the model name: person
? Select the data-source to attach person to: db (memory)
? Select model's base class PersistedModel
? Expose person via the REST API? Yes
? Custom plural form (used to build REST URL): people
? Common model or server only? common
When you have pressed return on the last question you'll be asked for the properties you want to create.
Enter an empty property name when done.
? Property name: firstname
invoke loopback:property
? Property type: string
? Required? No
? Default value[leave blank for none]:
Let's add another person property.
Enter an empty property name when done.
? Property name: lastname
invoke loopback:property
? Property type: string
? Required? No
? Default value[leave blank for none]:
Please enter a space for the default value. Otherwise loopback complains
If you now look at your folders and files you'll see that a common/models folder with two files in it have been created
├── client
│ └── README.md
├── common
│ └── models
│ ├── person.js
│ └── person.json
├── node_modules
├── package.json
└── server
├── ...
└── ...
The json file contains your model description
{
"name": "person",
"plural": "people",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"firstname": {
"type": "string"
},
"lastname": {
"type": "string"
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
As you can see here some properties and objects/arrays were added. The most notable entry at this point is "idInjection": true
. This says that an id column will be automatically added by loopback. You don't have to take care of it by yourself. Even the id value will automatically be managed by loopback at runtime.
At this time you could already start your server and use the standard REST API that is exposed by loopback to manage your people data.
But we want to talk OData. Here n-odata-server comes into play.
The installation of n-odata-server is as easy as the last steps. Just enter
npm install n-odata-server --save
into you command line window. You now can see that there is an additional folder under node_modules
.
├── node_modules
│ ├── ...
│ ├── ...
│ ├── n-odata-server
│ ├── ...
To be able to use n-odata-server you have to configure it. But that's also dead easy.
Just open the file
server/component-config.json
and add the "n-odata-server" block to the end. Your file should then look like this:
{
"loopback-component-explorer": {
"mountPath": "/explorer"
},
"n-odata-server": {
"path": "/odata/*",
"odataversion": "2"
}
}
The path
entry tells loopback that it should forward each http request starting with /odata/
to the n-odata-server package.
The odataversion
entry says that the n-odata-server should use OData Version 2 (V4 is currently only supported experimentally).
Additionally to n-odata-server we have to install another package. This package is body-parser
. So run the following command in your terminal window.
npm install body-parser --save
The body-parser parses the body of a http request and adds it to the express request object at runtime. n-odata-server needs the body for for POST and PUT requests.
In your server.js file you have to tell express which runs under the hood that it should parse the body of any request.
Add the first and last line of the following snippet before and after the already available second line of the snippet in file
server/server.js
var bodyParser = require('body-parser');
var app = module.exports = loopback();
// parse application/json
app.use(bodyParser.json());
node .
(don't forget the dot at the end)
Your server is started when you get the following message
[2016-07-08 18:35:53.010] [INFO] base - component config set to {
"path": "/odata/*",
"odataversion": "2",
"maxpagesize": 1000,
"odataPrefix": "odata"
}
Web server listening at: http://0.0.0.0:3000
Browse your REST API at http://0.0.0.0:3000/explorer
To get e.g. the service document of your OData serivce execute the following http request. Here we use curl but you can of cause also use your browser or a REST client like PostMan plugin for Chrome.
curl -X GET -H "Accept: Accept: application/json" "http://0.0.0.0:3000/odata/"
The server should return this (output is formatted to make it more readable)
{
"d": {
"EntitySets": [
{
"name": "people",
"url": "people"
}
]
}
}
To retrieve the metadata document of your server just invoke this
curl -X GET -H "Accept: Accept: application/atom+xml" -H "Content-Type: application/atom+xml" "http://0.0.0.0:3000/odata/\$metadata"
(the \ is needed only with curl to escape the $ sign) You will retrieve this answer
<?xml version="1.0" encoding="UTF-8"?>
<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" Version="1.0">
<edmx:DataServices m:DataServiceVersion="2.0">
<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" Namespace="NODATASERVER">
<EntityType Name="person">
<Key>
<PropertyRef Name="id"/>
</Key>
<Property Name="firstname" Type="Edm.String"/>
<Property Name="lastname" Type="Edm.String"/>
<Property Name="id" Type="Edm.Int32"/>
</EntityType>
<Association/>
<EntityContainer Name="NODATASERVER" m:IsDefaultEntityContainer="true">
<EntitySet Name="people" EntityType="NODATASERVER.person"/>
<AssociationSet/>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
To persist a person enter the following command.
curl -X POST -H "Content-Type: application/json" -d '{
"firstname": "Helmut",
"lastname": "Tammen"
}' "http://0.0.0.0:3000/odata/people"
You will receive the following result.
{
"d": {
"firstname": "Helmut",
"id": 1,
"lastname": "Tammen"
}
}
To get all person object from your database enter the following command.
curl -X GET -H "Accept: Accept: application/json" -H "Content-Type: application/json" "http://0.0.0.0:3000/odata/people"
You will get something like this.
{
"d": {
"results": [
{
"__metadata": {
"type": "NODATASERVER.person",
"uri": "http://0.0.0.0:3000/odata/people('1')"
},
"firstname": "Helmut",
"id": 1,
"lastname": "Tammen"
}
]
}
}