So, I built a thing. Part of building any product like AutomatedApi is actually taking the thing for a spin. I was inspired by things like 750words recently and I thought I’d give something like that a whirl. What I didn’t want to do was manage a database and build an api and then have to manage both deployments in some attempt to be all ‘microservice-y’. Fair warning, the app itself is rough, my purpose was to get something built fairly quickly so I haven’t cleaned up error pages or failed login stuff, what you get when navigating to this POC demo is without second and third pass refinements. Enjoy.

The Plan

The app I had in mind should be a short build ending in a fully functional diary/logging application that I could post up somewhere and have people actually interact with, even potentially sign up to use for as long as it remains online. I present to you the AutomatedApi Daily Logger. It’s on a different login domain, so testing would require an account to be created there. I’m sure I’ll reuse that db for identity on other demo apps, but I promise not to ever look at that db directly…no one actually wants to manage more dbs, that’s kinda the point of AutomatedApi.

The Layout

I Rolled up a simple layout that i picked up from Pixelarity some time back and spun it into an ASP.NET Core web application with run of the mill identity management as suggested in .NET core documentation and tutorials. Essentially all of this could be hacked together using tutorials in something like 30 minutes to an hour. To keep things as simple as possible (it’s all designed to one page), if you’re not logged in - you’re asked to log in, and if you are - you should be able to make an entry and see that entry on the lower part of the screen.

I wanted the entries to be put together in a timeline, they’ve always interested me but I’ve never actually built any. As such, each entry will be comprised of only a few properties:

  1. a timestamp
  2. a text entry
  3. a link to a user id

The Build

To achieve that, I submitted this to the Automated API Portal when creating a new API.

{
  "openapi": "3.0.1",
  "info": {
    "title": "",
    "version": "1"
  },
  "paths": { },
  "components": {
    "schemas": {
      "UserDailyLog": {
        "properties": {
          "UserId": {
            "type": "string"
          },
          "LogEntry": {
            "type": "string"
          },
            "EntryDate":{
              "type":"datetime"
            }
        }
      }
    }
  }
}

I knew this would generate a service with a 4 properties (including the autogenerated id), so I then built some data transfer objects with with the following shapes as suggested by the documentation for POSTing new entries and GETting collections of them with a simple filter on UserId.

The Internal Model

    public class UserDailyLog
    {
        public Guid UserDailyLogId { get; set; }
        public string UserId { get; set; }
        public string LogEntry { get; set; }
        public DateTime EntryDate { get; set; }
    }

DTOs and Collection Models

The first one just inherits from my internal one, it was built with that intent and why not leverage something if we know it has the same shape.

    public class UserDailyLogDTO: UserDailyLog
    {
    }

    public class UserDailyLogForCreationDTO
    {
        public string UserId { get; set; }
        public string LogEntry { get; set; }
        public DateTime EntryDate { get; set; }
    }

And for collections, I needed an object for the metadata so I could eventually build some paging mechanism.

    public class AutomatedApiMetadata
    {
        public int TotalCount { get; set; }
        public int PageSize { get; set; }
        public int CurrentPage { get; set; }
        public int TotalPages { get; set; }
        public string PreviousPageLink { get; set; }
        public string NextPageLink { get; set; }

    }

    public class UserDailyLogDtoCollection
    {
        public List<UserDailyLogDTO> UserDailyLogs { get; set; }
        public AutomatedApiMetadata PaginationMetadata { get; set; }
    }

Nothing too complicated. I don’t want to build updates in, so I only built to use the POST method and the GET for collections. I already had some http client logic built in at that point using a utility I’ll be sharing separately on this blog, so all I had to do at that point was hook up the Urls that would be needed and make sure it worked in the razor pages I’d put already together. And BONUS, by the time I’d finished writing these classes, the service was ready and available through the automatedapi gateway, so I was ready to roll.

For the getter I ended up assembling this for the getter url.

var opUri = new Uri($"https://gateway.automatedapi.com/AutomatedApi/UserDailyLogs?searchQuery={User.FindFirst(ClaimTypes.NameIdentifier).Value}");

and this for the POST url

var opUri = new Uri($"https://gateway.automatedapi.com/AutomatedApi/UserDailyLogs");

The end result worked out pretty nicely. Total time to live: 2 hours, but only because I found and fixed a bug in the core product while I was building this out.

A couple notes

  1. I realize that I’m using a userid in a general search context. This introduces some risk but only if someone stumbles onto the same GUID and includes it in their log entry, extremely unlikely and this is only a toy app.
  2. Having built this, I think I see a way to build a better search term that maps by id. I’ll add that to the list for October release.
  3. Someone better shoot me an email to remind me to post that http client code to a github repo, eventually I’ll slam it into a nuget package too, I’d really like to just be able to download that with a click, but for now, copying into new projects isn’t so bad.

Cheers folks!