Web API in detail
You can consume API services in a RESTful manner via HTTPS calls by using HTTPS methods:
GET
: Get the resource.POST
: Create a new resource.PUT
: Update the existing resource.PATCH
: Update a part of the existing resource.DELETE
: Remove the resource.
OData query options (such a $expand
, $filter
, $top
, $select
, etc.) and API specific options (such as SmApiFulfillCountry
) can be passed via query strings.
Paging is required if you want to query multiple records. You can do this with the OData query options $skip
and $top
. The maximum value for $top
is returned in the Smartstore-Api-MaxTop
header field. This value is configurable by the store owner.
Due to Basic Authentication, it is mandatory to send requests via HTTPS. HTTP will return a 421 Misdirected Request
status code. The only exception is that developers can send requests via HTTP to their local development environment.
A request body must be UTF-8 encoded.
Request HTTP header fields
Accept: application/json
yes
Only application/json is valid.
Accept-Charset: UTF-8
yes
Prefer: return=representation
no
Can be sent for PUT and PATCH requests if the API should answer with status code 200
and entity content response, otherwise 204 No Content
is returned.
Response HTTP header fields
Smartstore-Api-AppVersion: 5.1.0.0
Smartstore version used by the store.
Smartstore-Api-Version: 1 5.0
The highest API version supported by the server (unsigned integer) and the version of the installed API module (floating-point value).
Smartstore-Api-MaxTop: 120
The maximum value for OData $top
query option. The default value is 120
and is configurable by store owner.
Smartstore-Api-Date: 2022-11-11T14:35:33.7772907Z
The current server date and time in ISO-8601 UTC.
Smartstore-Api-CustomerId: 1234
The customer identifier of the authenticated API user. Returned only if authentication is successful.
Smartstore-Api-AuthResultId: 5
The ID of the reason why the request was denied. Returned only if the authentication failed.
See authentication.
Smartstore-Api-AuthResultDesc: UserDisabled
A short description of the reason why the request was denied. Returned only if the authentication failed.
See authentication.
WWW-Authenticate: Basic realm="Smartstore.WebApi", charset="UTF-8"
The name of the failed authentication method.
Query options
OData query options allow manipulation of data queries like sorting, filtering, paging etc. They are sent in the query string of the request URL.
Custom query options should make the Smartstore Web API easier to use, especially when working with entity relationships.
SmApiFulfill{property_name}
Entities often have multiple relationships with other entities. In most cases, an ID must be set to create or modify them. But often you do not know the ID. To reduce the number of API round trips, this option can set an entity relationship indirectly.
For example, imagine you want to add a German address, but you don't have the ID of the German country entity, required for address insertion. Instead of calling the API again to get the ID, you can add the query option SmApiFulfillCountry=DE
and the API will automatically resolve the relationship.
The API can fulfill the following properties:
Country
The two or three letter ISO country code.
SmApiFulfillCountry=USA
StateProvince
The abbreviation of a state or province.
SmApiFulfillStateProvince=CA
Language
The culture of a language.
SmApiFulfillLanguage=de-DE
Currency
The ISO code of a currency.
SmApiFulfillCurrency=EUR
SmApiFulfill
sets the relationship only if none exists yet. An existing relationship cannot be modified with this option.
Web API and modules
If a module extends the domain model with its own entities, these can also be integrated into the Web API using ODataModelProviderBase or IODataModelProvider. This allows the module developer to make their entities externally accessible without having to create their own Web API.
The Smartstore.Blog module registers two entities BlogComment
and BlogPost
through the ODataModelBuilder
using the following BlogODataModelProvider
.
internal class BlogODataModelProvider : ODataModelProviderBase
{
public override void Build(ODataModelBuilder builder, int version)
{
builder.EntitySet<BlogComment>("BlogComments");
builder.EntitySet<BlogPost>("BlogPosts");
}
public override Stream GetXmlCommentsStream(IApplicationContext appContext)
=> GetModuleXmlCommentsStream(appContext, "Smartstore.Blog");
}
Next, you need to add an API controller for each entity. It is recommended that you create a subfolder called Api in the controller folder of the module. Inherit your controller from WebApiController, as shown in the example.
/// <summary>
/// The endpoint for operations on the BlogComment entity.
/// </summary>
public class BlogCommentsController : WebApiController<BlogComment>
{
[HttpGet("BlogComments"), ApiQueryable]
[Permission(BlogPermissions.Read)]
public IQueryable<BlogComment> Get()
{
var query = Db.CustomerContent
.AsNoTracking()
.OrderByDescending(x => x.CreatedOnUtc)
.OfType<BlogComment>();
return query;
}
[HttpGet("BlogComments({key})"), ApiQueryable]
[Permission(BlogPermissions.Read)]
public SingleResult<BlogComment> Get(int key)
{
return GetById(key);
}
[HttpGet("BlogComments({key})/BlogPost"), ApiQueryable]
[Permission(BlogPermissions.Read)]
public SingleResult<BlogPost> GetBlogPost(int key)
{
return GetRelatedEntity(key, x => x.BlogPost);
}
[HttpPost]
[Permission(BlogPermissions.Create)]
public async Task<IActionResult> Post([FromBody] BlogComment entity)
{
return await PostAsync(entity);
}
[HttpPut]
[Permission(BlogPermissions.Update)]
public async Task<IActionResult> Put(int key, Delta<BlogComment> model)
{
return await PutAsync(key, model);
}
[HttpPatch]
[Permission(BlogPermissions.Update)]
public async Task<IActionResult> Patch(int key, Delta<BlogComment> model)
{
return await PatchAsync(key, model);
}
[HttpDelete]
[Permission(BlogPermissions.Delete)]
public async Task<IActionResult> Delete(int key)
{
return await DeleteAsync(key);
}
}
The BlogCommentsController
defines OData Web API endpoints to get, create, update, patch (partially update), and delete blog comments. It also defines an endpoint to get the associated blog post through the BlogPost
navigation property. See the Web API module controllers for more endpoint definitions.
Override ODataModelProviderBase.GetXmlCommentsStream
to automatically include your code comments in the Swagger documentation of the Web API. To do this, the Documentation File option must also be enabled in the module project settings. The path to the XML documentation file should be left empty. This will export your code comments to an XML file with the same name as the module at compile time (Smartstore.Blog.xml in the example above), which will then be used by the Web API.
Last updated
Was this helpful?