When creating new content, applications, and/or other custom data and services within Telligent Community, you can expose those services for external integration via REST in the same way that the built-in APIs are exposed externally via REST. This offers immense flexibility in
[toc]
When Should I Use REST Endpoints?
Anytime you want to enable applications outside of Telligent Community to interact with your custom-added entities, you should expose the entities via REST. This can also be used in the UI for AJAX operations using your entities.
Our example will illustrate our standard recommended REST endpoint set for entities: Create, Update, Delete, Get, and List.
Required DLL references:
- Telligent.Evolution.Components
- Telligent.Evolution.Rest
Sample Content
The first step in the process is to have custom data or service written to create REST endpoints against. Here we present a simple example class, Dog:
using System; namespace Telligent.Evolution.Samples { public class Dog { public Guid Id { get; set; } public string Name { get; set; } public string Breed { get; set; } } }
For the sake of this demo, we assume a supporting service exists to perform CRUD operations on this object. We refer to it as DogService and assume its methods take all required parameters individually, and group all optional parameters into an Dog<MethodName>Options class.
Registering REST Routes
Implementing IRestEndpoints requires a Register() method that provides you with a controller with which to register your REST routes. Routes will always start with the standard Telligent Community REST URL (<siteurl> + "/api.ashx/v2/"); we will define what the rest of the url should look like for each desired method. IRestEndpoints is also an IPlugin, so you will need to implement the basic IPlugin interface as well.
The declaration of the endpoint is actually fairly simple. The parameters are:
- int version: Used to track breaking changes to your endpoints. Part of the infrastructure of APIs is that they remain consistent so that third party applications do not need to constantly update to prevent from breaking. If you make changes to an endpoint, it is very highly recommended to instead create a new endpoint with updated version number
- string relativeUrl: This is the addition to the base REST URL to identify this method to the handler. Together with the HTTP method, this makes the unique signature for this method.
- object parameterDefaults:
- object parameterContstraints:
- HttpMethod method: Corresponds to the standard HTTP methods (GET, POST, PUT, DELETE).
- Func<IRestRequest, IRestResponse> handler:
public void Register(IRestEndpointController restRoutes) { restRoutes.Add(1, "dogs", new { resource = "dog", action = "create" }, null, HttpMethod.Post, CreateDog); restRoutes.Add(1, "dog/{id}", new { resource = "dog", action = "update" }, null, HttpMethod.Put, UpdateDog); restRoutes.Add(1, "dog/{id}", new { resource = "dog", action = "delete" }, null, HttpMethod.Delete, DeleteDog); restRoutes.Add(1, "dog/{id}", new { resource = "dog", action = "show" }, null, HttpMethod.Get, GetDog); restRoutes.Add(1, "dogs", new { resource = "dog", action = "list" }, null, HttpMethod.Get, ListDogs); }
The functions for performing each action are declared separately. First though, we must create a Response object so that we can send the data in a known format.
[XmlRoot(ElementName = "Response")] [RestAction(RestAction.Show, "achievement")] public class DogResponse : IRestResponse { private Dog _dog; public Dog Dog { get { return _dog; } set { _dog = value; } } public string Name { get { return "Dog"; } } public object Data { get { return _dog; } } public string[] Errors { get; set; } }
Each Rest method accepts an IRestRequest object and returns and IRestResponse object. The request object is expected to have all parameters contained in the PathParameters object. Depending on if a parameter is required or optional, an error response can be returned if the request does not fulfill the requirements. If all required parameters are included, each can be parsed and then used with the underlying internal service to perform the operation requested.
Create:
public IRestResponse CreateDog(IRestRequest request) { var response = new DogResponse(); if (!request.PathParameters.ContainsKey("Name")) { response.Errors = new[] { "Name is required" }; return response; } var name = request.PathParameters["Name"].ToString(); var options = new DogCreateOptions(); if (request.PathParameters.ContainsKey("Breed")) options.Breed = request.PathParameters["Breed"].ToString(); try { var createdDog = DogService.Create(name, options); response.Dog = createdDog; } catch (Exception ex) { response.Errors = new[] { "Error: '{0}'", ex.ToString() }; } return response; }
Update:
public IRestResponse UpdateDog(IRestRequest request) { var response = new DogResponse(); if (!request.PathParameters.ContainsKey("Id")) { response.Errors = new[] { "Id is required" }; return response; } var id = Guid.Parse(request.PathParameters["Id"].ToString()); var options = new DogUpdateOptions(); if (request.PathParameters.ContainsKey("Name")) options.Name = request.PathParameters["Name"].ToString(); if (request.PathParameters.ContainsKey("Breed")) options.Breed = request.PathParameters["Breed"].ToString(); try { var createdDog = DogService.Update(id, options); response.Dog = createdDog; } catch (Exception ex) { response.Errors = new[] { "Error: '{0}'", ex.ToString() }; } return response; }
Delete:
public IRestResponse DeleteDog(IRestRequest request) { var response = new DefaultRestResponse(); if (!request.PathParameters.ContainsKey("Id")) { response.Errors = new[] { "Id is required" }; return response; } var id = Guid.Parse(request.PathParameters["Id"].ToString()); try { DogService.Delete(id); } catch (Exception ex) { response.Errors = new[] { "Error: '{0}'", ex.ToString() }; } return response; }
Get:
public IRestResponse GetDog(IRestRequest request) { var response = new DogResponse(); var options = new DogGetOptions(); if (!request.PathParameters.ContainsKey("Id")) { response.Errors = new[] { "Id is required" }; return response; } options.Id = Guid.Parse(request.PathParameters["Id"].ToString()); try { var dog = DogService.Get(options); response.Dog = dog; } catch (Exception ex) { response.Errors = new[] { "Error: '{0}'", ex.ToString() }; } return response; }
List:
public IRestResponse ListDogs(IRestRequest request) { var response = new DefaultRestResponse(); var options = new DogListOptions(); if (request.PathParameters.ContainsKey("Name")) options.Name = request.PathParameters["Name"].ToString(); if (request.PathParameters.ContainsKey("Breed")) options.Breed = request.PathParameters["Breed"].ToString(); if (request.PathParameters.ContainsKey("SortBy")) options.SortBy = request.PathParameters["SortBy"].ToString(); if (request.PathParameters.ContainsKey("SortOrder")) options.SortOrder = request.PathParameters["SortOrder"].ToString(); if (request.PathParameters.ContainsKey("PageSize")) options.PageSize = Int32.Parse(request.PathParameters["PageSize"].ToString()); if (request.PathParameters.ContainsKey("PageIndex")) options.PageIndex = Int32.Parse(request.PathParameters["PageIndex"].ToString()); try { var dogs = DogService.List(options); response.Name = "Dogs"; response.Data = dogs; } catch (Exception ex) { response.Errors = new[] { "Error: '{0}'", ex.ToString() }; } return response; }
Using the Registered Routes
For information on making calls to REST end points, see REST API: Making Requests.