blob: a5f5427666b415845daad8265b41c31362ce80d0 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>basic</title>
<link rel="stylesheet" href="/css/pycco.css">
</head>
<body>
<div id="background"></div>
<div id='container'>
<div class='section'>
<div class='docs'><h1>basic</h1></div>
</div>
<div class='clearall'>
<div class='section' id='section-0'>
<div class='docs'>
<div class='octowrap'>
<a class='octothorpe' href='#section-0'>#</a>
</div>
</div>
<div class='code'>
<div class="highlight"><pre><span class="kn">import</span> <span class="n">endpoints</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext</span> <span class="kn">import</span> <span class="n">ndb</span>
<span class="kn">from</span> <span class="nn">protorpc</span> <span class="kn">import</span> <span class="n">remote</span>
<span class="kn">from</span> <span class="nn">endpoints_proto_datastore.ndb</span> <span class="kn">import</span> <span class="n">EndpointsModel</span></pre></div>
</div>
</div>
<div class='clearall'></div>
<div class='section' id='section-1'>
<div class='docs'>
<div class='octowrap'>
<a class='octothorpe' href='#section-1'>#</a>
</div>
<p>Transitioning an existing model is as easy as replacing <code>ndb.Model</code> with
<code>EndpointsModel</code>. Since <code>EndpointsModel</code> inherits from <code>ndb.Model</code>, you will have
the same behavior and more functionality.</p>
</div>
<div class='code'>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">EndpointsModel</span><span class="p">):</span></pre></div>
</div>
</div>
<div class='clearall'></div>
<div class='section' id='section-2'>
<div class='docs'>
<div class='octowrap'>
<a class='octothorpe' href='#section-2'>#</a>
</div>
<p>By default, the ProtoRPC message schema corresponding to this model will
have three string fields: <code>attr1</code>, <code>attr2</code> and <code>created</code>
in an arbitrary order (the ordering of properties in a dictionary is not
guaranteed).</p>
</div>
<div class='code'>
<div class="highlight"><pre> <span class="n">attr1</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">StringProperty</span><span class="p">()</span>
<span class="n">attr2</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">StringProperty</span><span class="p">()</span>
<span class="n">created</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">DateTimeProperty</span><span class="p">(</span><span class="n">auto_now_add</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span></pre></div>
</div>
</div>
<div class='clearall'></div>
<div class='section' id='section-3'>
<div class='docs'>
<div class='octowrap'>
<a class='octothorpe' href='#section-3'>#</a>
</div>
<p>Use of this decorator is the same for APIs created with or without
<code>endpoints-proto-datastore</code>.</p>
</div>
<div class='code'>
<div class="highlight"><pre><span class="nd">@endpoints.api</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;myapi&#39;</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="s">&#39;v1&#39;</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s">&#39;My Little API&#39;</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">MyApi</span><span class="p">(</span><span class="n">remote</span><span class="o">.</span><span class="n">Service</span><span class="p">):</span></pre></div>
</div>
</div>
<div class='clearall'></div>
<div class='section' id='section-4'>
<div class='docs'>
<div class='octowrap'>
<a class='octothorpe' href='#section-4'>#</a>
</div>
<p>Instead of the <code>endpoints.method</code> decorator, we can use <code>MyModel.method</code> to
define a new endpoints method. Instead of having to convert a
ProtoRPC request message into an entity of our model and back again, we
start out with a <code>MyModel</code> entity and simply have to return one.
Since no overrides for the schema are specified in this decorator, the
request and response ProtoRPC message definition will have the three string
fields <code>attr1</code>, <code>attr2</code> and <code>created</code>.</p>
</div>
<div class='code'>
<div class="highlight"><pre> <span class="nd">@MyModel.method</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s">&#39;mymodel&#39;</span><span class="p">,</span> <span class="n">http_method</span><span class="o">=</span><span class="s">&#39;POST&#39;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;mymodel.insert&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">MyModelInsert</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">my_model</span><span class="p">):</span></pre></div>
</div>
</div>
<div class='clearall'></div>
<div class='section' id='section-5'>
<div class='docs'>
<div class='octowrap'>
<a class='octothorpe' href='#section-5'>#</a>
</div>
<p>Though we don't actively change the model passed in, two things happen:</p>
<ul><li>The entity gets an ID and is persisted</li>
<li>Since <code>created</code> is <code>auto_now_add</code>, the entity gets a new value for created</li></ul>
</div>
<div class='code'>
<div class="highlight"><pre> <span class="n">my_model</span><span class="o">.</span><span class="n">put</span><span class="p">()</span>
<span class="k">return</span> <span class="n">my_model</span></pre></div>
</div>
</div>
<div class='clearall'></div>
<div class='section' id='section-6'>
<div class='docs'>
<div class='octowrap'>
<a class='octothorpe' href='#section-6'>#</a>
</div>
<p>As <code>MyModel.method</code> replaces a ProtoRPC request message to an entity of our
model, <code>MyModel.query_method</code> replaces it with a query object for our model.
By default, this query will take no arguments (the ProtoRPC request message
is empty) and will return a response with two fields: <code>items</code> and
<code>nextPageToken</code>. <code>nextPageToken</code> is simply a string field for paging through
result sets. <code>items</code> is what is called a <code>MessageField</code>, meaning its value
is a ProtoRPC message itself; it is also a repeated field, meaning we have
an array of values rather than a single value. The nested ProtoRPC message
in the definition of <code>items</code> uses the same schema in <code>MyModel.method</code>, so each
value in the <code>items</code> array will have the fields <code>attr1</code>, <code>attr2</code> and <code>created</code>.
As with <code>MyModel.method</code>, overrides can be specified for both the schema of
the request that defines the query and the schema of the messages contained
in the <code>items</code> list. We'll see how to use these in further examples.</p>
</div>
<div class='code'>
<div class="highlight"><pre> <span class="nd">@MyModel.query_method</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s">&#39;mymodels&#39;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;mymodel.list&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">MyModelList</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">query</span><span class="p">):</span></pre></div>
</div>
</div>
<div class='clearall'></div>
<div class='section' id='section-7'>
<div class='docs'>
<div class='octowrap'>
<a class='octothorpe' href='#section-7'>#</a>
</div>
<p>We have no filters that we need to apply, so we just return the query
object as is. As we'll see in further examples, we can augment the query
using environment variables and other parts of the request state.</p>
</div>
<div class='code'>
<div class="highlight"><pre> <span class="k">return</span> <span class="n">query</span></pre></div>
</div>
</div>
<div class='clearall'></div>
<div class='section' id='section-8'>
<div class='docs'>
<div class='octowrap'>
<a class='octothorpe' href='#section-8'>#</a>
</div>
<p>Use of <code>endpoints.api_server</code> is the same for APIs created with or without
<code>endpoints-proto-datastore</code>.</p>
</div>
<div class='code'>
<div class="highlight"><pre><span class="n">application</span> <span class="o">=</span> <span class="n">endpoints</span><span class="o">.</span><span class="n">api_server</span><span class="p">([</span><span class="n">MyApi</span><span class="p">],</span> <span class="n">restricted</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class='clearall'></div>
<div class='section' id='section-9'>
<div class='docs'>
<div class='octowrap'>
<a class='octothorpe' href='#section-9'>#</a>
</div>
<p>Head on to the next sample <a href="/examples/basic_with_auth.html">basic_with_auth<a>
or head back to the <a href="/">main page</a>.</p>
</div>
</div>
<div class='clearall'></div>
</div>
</body>