Customize the Rest API
The Weavy REST API is more than just a set of predefined endpoints. You are free to modify existing methods as well as add your own logic.
The controllers that are shipped with the Server SDK are designed for the most common CRUD scenarios and to provide you with examples on how to organize your API, but there are often situations where you would want to perform custom actions or expose additional data in the responses.
A guiding principle has been that it is often more effective to write a custom endpoint that performs a number of actions, instead of making individual calls to a number of different endpoints, each with its own overhead in terms of network latency, parsing etc. The later approach is also more error prone and more complicated to recover from if an error occurs.
Built-in API methods
The code that make up the REST API is located in the Areas\Api
folder. API methods are defined in Web API controllers under the Areas\Api\Controllers
folder.
Each controller class serves and performs actions that relates to a distinct entity type (e.g. user, space, app).
You are free to modify and/or add API methods to serve your needs. Just keep in mind that this will add some complexity when you merge in changes from weavy-sln repo.
Adding custom API methods
When creating custom api methods you should do the following:
- Create a class extending the
Weavy.Web.Api.Controllers.WeavyApiController
- Add and implement methods and decorate them with the appropriate
[HttpVerb]
and[Route]
attributes.
Controllers and Actions
Your first step is to create a class extending Weavy.Web.Api.Controllers.WeavyApiController
.
A good convention is to place the file in the Areas\Api\Controllers
folder.
In this example we are adding a controller with an action method that creates some resources and then returns the result.
using System.Linq;
using System.Web.Http;
using System.Web.Http.Description;
using Weavy.Areas.Api.Models;
using Weavy.Core.Models;
using Weavy.Core.Services;
using Weavy.Web.Api.Controllers;
namespace Weavy.Areas.Api.Controllers {
[RoutePrefix("api")]
public class ExampleController : WeavyApiController {
[HttpPost]
[Route("example/configure")]
[ResponseType(typeof(ConfigurationResult))]
public IHttpActionResult Configure(Configuration model) {
// get or create the user
User user = UserService.GetByEmail(model.Email);
if (user == null) {
user = new User() { Email = model.Email, Username = UserService.MakeUniqueUsername(model.Email) };
user.Profile.Name = model.Name;
user = UserService.Insert(user);
}
// get or create the space
Space space = SpaceService.GetByKey(model.SpaceKey);
if (space == null) {
space = SpaceService.Insert(new Space() { Key = model.SpaceKey, Name = model.SpaceKey });
}
// add the user to the space if not member
if (!space.MemberIds.Any(x => x == user.Id)) {
SpaceService.AddMember(space.Id, user.Id);
}
// get or create the files app in the space
var app = AppService.GetApps<Files>(space.Id).FirstOrDefault();
if (app == null) {
app = AppService.Insert(new Files() { Name = "Files" }, space);
}
var result = new ConfigurationResult() {
App = app,
Space = space,
User = user
};
return Ok(result);
}
}
}
Attributes
Each action method typically has the following attributes:
- A HTTP method attribute describing the verbs that the method accepts.
- A Route attribute describing the URI template for the route.
- The ResponseType attribute is useful to indicate the return type of the IHttpActionResult and is used when generating the API documentation.
Optionally, you can decorate the controller class with the [RoutePrefix] attribute. This will make sure the routing prefix is prepended to all actions within the controller. We recommended that you use api.
To prevent route collisions we also recommend that your route attributes starts with the controller name.
In the example above our controller is called ExampleController
and we started our route with example.
In the example above the [RoutePrefix]
and [Route]
attributes are combined to form the final route api/example/configure.
Models
There are two models used in this example; the Configuration
and the ConfigurationResult
classes.
These are used as input to, and output from, the action and are placed in the Areas\Api\Models
folder.
using System.ComponentModel.DataAnnotations;
namespace Weavy.Areas.Api.Models {
public class Configuration {
[Required]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string Email { get; set; }
public string Name { get; set; }
[Required]
public string SpaceKey { get; set; }
}
}
Configuration.cs
using Weavy.Core.Models;
namespace Weavy.Areas.Api.Models {
public class ConfigurationResult {
public User User { get; set; }
public App App { get; set; }
public Space Space { get; set; }
}
}
ConfigurationResult.cs
Testing
You can test your api method by first retriving an access token from the /api/auth
endpoint
as described in the Authentication article
and then issuing a request to your api method:
POST /api/example/configure
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3Mi...
{
"email": "test@example.com",
"name": "Test Testsson",
"space_key": "e6469f67-a2a0-41f5-9efb-5991cf49ed4e"
}
Setting up Postman or a similar API client is recommended for testing scenarios.
Documentation
By default your custom api controllers and methods will be self documented on https://{your-weavy-url}/docs/[controller-name]
.
To opt-out of documentation, decorate your class or individual methods with the ApiExplorerSettingsAttribute attribute:
[ApiExplorerSettings(IgnoreApi = true)]
Troubleshooting
Because of the way .NET Web API is organized all controllers must have a unique class name within the solution. It does not help that their namespace makes them unique.
When adding usings
in the top of the classes, take care not to add the MVC
namespace version. Some of the types have an Web API and an MVC version.
Make sure to add the namespace that starts with System.Web.Http
and not System.Web.Mvc
.