DEV Community

Kevin Jump
Kevin Jump

Posted on • Edited on

Early Adopter's Guide to Umbraco v14 Packages: Communicating with the server! - Part 1

We are skipping ahead a few steps from the early adopter's series. There are still articles for 'how to get a dashboard, or tree, or section, or workspace working' posts to write, but this is fresh in my mind so here we go.


The code for this series of posts can be viewed here : https://github.com/KevinJump/TimeDashboard

On thing you are probibly going to want to do with a package at somepoint is communicate with the server from the front end. and i don't mean get a bit of content or list all the logged on users, i mean get something custom from the server.

to do this in Umbraco v13 or less you would have written an UmbracoAuthorizedApiController with some methods in it and called it with a $http.get or similar from angularJs.

with v14 its a little somewhat quite diffrent !

Context's, Repositories, Stores and Resources

Now we've jumped quite far ahead here, so we might have to assume we've already said what these things are in detail, but quickly.

  • Context is like a service, it's go the method you want to get things in your dashboard, etc. it also stores some values, which you can 'observe' for changes than might happen elsewhere.

  • Repositories handle the first part of getting things, they abstract away how the data is stored in your app

  • Stores are where the data is stored

  • Resources are the things that actually go fetch the data, in the case of the back office, these are the bits doing the http requests.

you don't have to have all of these, this is just the pattern adopted by umbraco, if you going for something simpler, you can in theory call resources from the elements, or a context, and it will maybe work

1. Resources.

Lets start at the bottom, what you need is code to go fetch things from the server.

but first ! you need something on the server to fetch from. so are you sitting down...

! UmbracoAuthorizedApiController no longer exists in Umbraco v14 !

Yes we are going at have to re-write the api-controller element of our code, to get it working (nicely) with v14.

but marking up your api controller isn't to bad. If we follow the pattern of the Backoffice Management Api's we first have a base class:

[ApiController]
[BackOfficeRoute("time/api/v{version:apiVersion}/time")]
[Authorize(Policy = "New" + AuthorizationPolicies.BackOfficeAccess)]
[MapToApi("time")]
public class TimeDashboardControllerBase
{}
Enter fullscreen mode Exit fullscreen mode

and then we split our methods out in to child controllers, you don't have to do this, it just makes some of the mangement and the documentation easier later on. so here we have a child controller for getting time/date

[ApiVersion("1.0")]
[ApiExplorerSettings(GroupName = "time")]
public class TimeDashboardTimesController  : TimeDashboardControllerBase
{
    [HttpGet("time")]
    [ProducesResponseType(typeof(string), 200)]
    public string GetTime()
        => DateTime.Now.ToString("T");

    [HttpGet("date")]
    [ProducesResponseType(typeof(string), 200)]
    public string GetDate() 
        => DateTime.Now.ToString("D");
}
Enter fullscreen mode Exit fullscreen mode

there is a bit more markup than you might have seen in v13 - but its much more standard, when you look at how apicontrollers work in Asp.net Core.

Swagger.

Now you have an API, the next thing we need to do, is get a OpenApi spec for it, and you can do that by defining the swagger config for Api name (we've used 'time').

in a composer you need to configure your swagger config.

internal class ConfigureSwaggerGenOptions : IConfigureOptions<SwaggerGenOptions>
{
    public void Configure(SwaggerGenOptions options)
    {
        options.SwaggerDoc(
            "time",
            new OpenApiInfo
            {
                Title = "Time Management Api",
                Version = "Latest",
                Description = "Time from the server"
            });

        options.OperationFilter<TimeBackOfficeSecurityRequirementsOperationFilter>();
    }
}
Enter fullscreen mode Exit fullscreen mode

here we have used the IConfigureOptions interface. so our composer actually looks like this:

public class TimeComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.Services.ConfigureOptions<ConfigureSwaggerGenOptions>();
    }
}
Enter fullscreen mode Exit fullscreen mode

with this all set, visiting the swagger url on the site (https://yoursite/umbraco/swagger) should show you the api in the drop down:

Swagger dropdown in Umbraco

and the api should look something like this :

Swagger Api screen showing methods

Congratulations, you now have a management style api for your server, now we just need to call it.

Generating a client.

Update : 10th April 2024
The codegen client has now been updated to @hey-api/opengen-ts it is mostly the same but there are some subtle differences in naming and options.
The content below has been updated to reflect this.
for more info see our updated Codegen post for more details.

Working out how to call and manage the endpoints from your front end application can be a pain, thankfully we don't have to do that, because with a swagger.json file we can autogenerate the typescript client for our api!.

Umbraco uses a tool called. openapi-typescript-codegen for this, and it does excatly what you might expect it to.

Umbraco's tool of choice is now @hey-api\now openapi-ts

> Note: the tool seems to not like this setup past version 0.25, so for now install version 0.25 no higher.

you can call it, with either a file or a url and it will generate an typescript client for your code.

we have added the following to our package.json

"scripts": {
  "generate": "openapi-ts 
      --input http://localhost:123/umbraco/swagger 
      --output src/api 
      --debug true
      --enums typescript 
      --lint true 
      --schemas false"
}
Enter fullscreen mode Exit fullscreen mode

and we can then run it.

npm run generate
Enter fullscreen mode Exit fullscreen mode

and we get a client in the src/api folder.

this is the resources part of our **context, repository, store, resources **grouping.

next: the store !

Top comments (1)

Collapse
 
josemarcenaro profile image
Jose Marcenaro • Edited

Note: you might have issues generating the OpenApi code if you are running on https://localhost:NNNN (self-signed certificate)

If that is the case, add an alternative hostname of http://127.0.0.1:NNNN in launchsettings.json, and use that address for the openapi input argument.