Click here to Skip to main content
15,893,381 members

Dominic Burford - Professional Profile



Summary

Follow on Twitter LinkedIn      Blog RSS
6,554
Author
2,053
Authority
9,852
Debator
8
Editor
100
Enquirer
212
Organiser
2,954
Participant
I am a professional software engineer and technical architect with over twenty years commercial development experience with a strong focus on the design and development of web and mobile applications.

I have experience of architecting scalable, distributed, high volume web applications that are accessible from multiple devices due to their responsive web design, including architecting enterprise service-oriented solutions. I have also developed enterprise mobile applications using Xamarin and Telerik Platform.

I have extensive experience using .NET, ASP.NET, Windows and Web Services, WCF, SQL Server, LINQ and other Microsoft technologies. I am also familiar with HTML, Bootstrap, Javascript (inc. JQuery and Node.js), CSS, XML, JSON, Apache Cordova, KendoUI and many other web and mobile related technologies.

I am enthusiastic about Continuous Integration, Continuous Delivery and Application Life-cycle Management having configured such environments using CruiseControl.NET, TeamCity and Team Foundation Services. I enjoy working in Agile and Test Driven Development (TDD) environments.

Outside of work I have two beautiful daughters. I am also an avid cyclist who enjoys reading, listening to music and travelling.

 

Reputation

Weekly Data. Recent events may not appear immediately. For information on Reputation please see the FAQ.

Privileges

Members need to achieve at least one of the given member levels in the given reputation categories in order to perform a given action. For example, to store personal files in your account area you will need to achieve Platinum level in either the Author or Authority category. The "If Owner" column means that owners of an item automatically have the privilege. The member types column lists member types who gain the privilege regardless of their reputation level.

ActionAuthorAuthorityDebatorEditorEnquirerOrganiserParticipantIf OwnerMember Types
Have no restrictions on voting frequencysilversilversilversilver
Bypass spam checks when posting contentsilversilversilversilversilversilvergoldSubEditor, Mentor, Protector, Editor
Store personal files in your account areaplatinumplatinumSubEditor, Editor
Have live hyperlinks in your profilebronzebronzebronzebronzebronzebronzesilverSubEditor, Protector, Editor
Have the ability to include a biography in your profilebronzebronzebronzebronzebronzebronzesilverSubEditor, Protector, Editor
Edit a Question in Q&AsilversilversilversilverYesSubEditor, Protector, Editor
Edit an Answer in Q&AsilversilversilversilverYesSubEditor, Protector, Editor
Delete a Question in Q&AYesSubEditor, Protector, Editor
Delete an Answer in Q&AYesSubEditor, Protector, Editor
Report an ArticlesilversilversilversilverSubEditor, Mentor, Protector, Editor
Approve/Disapprove a pending ArticlegoldgoldgoldgoldSubEditor, Mentor, Protector, Editor
Edit other members' articlesSubEditor, Protector, Editor
Create an article without requiring moderationplatinumSubEditor, Mentor, Protector, Editor
Approve/Disapprove a pending QuestionProtector
Approve/Disapprove a pending AnswerProtector
Report a forum messagesilversilverbronzeProtector, Editor
Approve/Disapprove a pending Forum MessageProtector
Have the ability to send direct emails to members in the forumsProtector
Create a new tagsilversilversilversilver
Modify a tagsilversilversilversilver

Actions with a green tick can be performed by this member.


 
GeneralWriting flexible code Pin
Dominic Burford22-Jan-18 23:58
professionalDominic Burford22-Jan-18 23:58 
GeneralA cautionary tale of over-confidence in your own opinions Pin
Dominic Burford22-Dec-17 1:57
professionalDominic Burford22-Dec-17 1:57 
GeneralWhat lies ahead in 2018 Pin
Dominic Burford21-Dec-17 0:18
professionalDominic Burford21-Dec-17 0:18 
GeneralTemplated HTML emails using RazorEngine Pin
Dominic Burford30-Nov-17 4:49
professionalDominic Burford30-Nov-17 4:49 
GeneralSending emails using Azure Sendgrid service Pin
Dominic Burford29-Nov-17 11:18
professionalDominic Burford29-Nov-17 11:18 
GeneralBuilding native enterprise apps is (probably) the wrong approach Pin
Dominic Burford28-Nov-17 1:05
professionalDominic Burford28-Nov-17 1:05 
GeneralAppropriate vs Consistent Pin
Dominic Burford9-Nov-17 3:24
professionalDominic Burford9-Nov-17 3:24 
GeneralCreating Generic RESTful API Services Pin
Dominic Burford20-Oct-17 5:01
professionalDominic Burford20-Oct-17 5:01 
I have recently been designing the RESTful API's for a new application I'm involved in building. There are likely to be dozens or even hundreds of API's required by the application once it is fully complete. My goal when thinking about designing these RESTful API's was how to implement them in such a way as to reduce the exposed surface area to the client, such that fewer RESTful API's would be required to fulfill all service requests.

My thought process got me wondering if a single RESTful endpoint would be sufficient to handle all CRUD operations. This would need to handle multiple data types such as users, quotes, vehicles, purchase orders etc (the application is aimed at the fleet management sector) for the application. Usually a single endpoint would be created for each of the different data types i.e. a single RESTful endpoint for handling all driver CRUD operations, a single RESTful endpoint for handling all vehicle CRUD operations.

As I stated previously though, I wanted to design the RESTful API's in such a way as to reduce the exposed surface area and therefore try to perform all these CRUD operations using a single RESTful API.

After some trial and error, I got this working using what turned out to be a simple design pattern. I'll explain the design pattern for the GET (read) operations, and leave the others as an exercise for the reader to work out.

For each GET operation I pass two parameters. The first parameter identifies the type of query that is required and is a unique string identifier. It can hold values such as "getuserbyemail", "getuserpermissions", "getallusers". The second parameter is a JSON array structure containing key-value pairs of the values needed to fulfill the GET operation. As such it can contain a user's email address, a user's ID, a vehicle registration and so on.

Example JSON array structure.

HTML
{"QuerySearchTerms":{"email":"test@mycompany.co.uk"}}
The code for the GET request receives these two parameters on the querystring. After some initial validation checks (such as ensuring the request is authorised, time-bound and that both parameters are valid), it then processes the request.

The first querystring parameter informs the RESTful API what type of request is being made, and so therefore what elements to extract from the JSON array (which is the second querystring parameter). Here is the array structure that is passed to the GET request implemented in C#. This array structure can easily be (de)serialised and passed as a string parameter to the request.

C#
[DataContract]
    public class WebQueryTasks
    {
        [DataMember]
        public Dictionary<string, object> QuerySearchTerms { get; set; }

        /// <summary>
        /// Default constructor
        /// </summary>
        public WebQueryTasks()
        {
            this.QuerySearchTerms = new Dictionary<string, object>();
        }
    }
Here is the skeleton code for the GET request. For clarity I have removed the logging, the validation checks and kept the code as simple as possible.

C#
public string WebGetData(string queryname, string queryterms)
        {
            //initial checks such as validation and parameter checking

            try
            {
		//deserialise the JSON array structure
                WebQueryTasks query = ManagerHelper.SerializerManager().DeserializeObject<WebQueryTasks>(queryterms);
                if (query == null || !query.QuerySearchTerms.Any())
                {
                    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, new HttpError("Unable to deserialise search terms.")));
                }
                
                object temp;
                string webResults;
		//detemine the type of the query
                switch (queryname.ToLower())
                {
                    case WebTasksTypeConstants.GetCompanyByName:
                        webResults = this._userService.GetQuerySearchTerm("name", query);
                        if (!string.IsNullOrEmpty(webResults))
                        {
                            temp = this._companiesService.Find(webResults);
                        }
                        else
                        {
                            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, new HttpError("Unable to locate query search term(s).")));
                        }
                        break;
                    case WebTasksTypeConstants.GetUserByEmail:
                        webResults = this._userService.GetQuerySearchTerm("email", query);
                        if (!string.IsNullOrEmpty(webResults))
                        {
                            temp = this._userService.FindByEmail(webResults);
                        }
                        else
                        {
                            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, new HttpError("Unable to locate query search term(s).")));
                        }
                        break;
                    default:
                        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest,
                            new HttpError($"Unknown query type {queryname}.")));
                }
                var result = ManagerHelper.SerializerManager().SerializeObject(temp);
                return result;
            }
            catch (Exception ex)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, new HttpError("Exception servicing request.")));
            }
        }
I have applied the same design pattern to all the requests (POST, PUT, GET and DELETE). I pass in the same two parameters on the querystring, and the RESTful API determines what needs to be processed, and fetches the relevant values from the JSON array to process it. All data is returned in JSON format.

I have found this design pattern to be extremely flexible, extensible and easy to work with. It allows for all / any type of request to be made in a very simple manner. I have impemented full CRUD operations on a number of different data types all without a problem using this design pattern.
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C.A.R. Hoare

Home | LinkedIn | Google+ | Twitter

GeneralIs your software team a democracy or a dictatorship? Pin
Dominic Burford16-Oct-17 21:44
professionalDominic Burford16-Oct-17 21:44 
GeneralSimplifying updating data Pin
Dominic Burford21-Sep-17 22:46
professionalDominic Burford21-Sep-17 22:46 
GeneralWhen 100% code coverage is not always enough Pin
Dominic Burford21-Jul-17 5:11
professionalDominic Burford21-Jul-17 5:11 
GeneralThat's the app in the app stores Pin
Dominic Burford18-Jul-17 5:00
professionalDominic Burford18-Jul-17 5:00 
GeneralDefensive Programming Pin
Dominic Burford28-Jun-17 7:23
professionalDominic Burford28-Jun-17 7:23 
GeneralMy first year - How time flies Pin
Dominic Burford19-Jun-17 1:40
professionalDominic Burford19-Jun-17 1:40 
GeneralShould software architects write code? Pin
Dominic Burford16-Jun-17 4:22
professionalDominic Burford16-Jun-17 4:22 
GeneralEnsuring your data is safe with Azure SQL Database Pin
Dominic Burford2-Jun-17 2:24
professionalDominic Burford2-Jun-17 2:24 
GeneralWhat makes a Senior Software Engineer? Pin
Dominic Burford30-May-17 21:53
professionalDominic Burford30-May-17 21:53 
GeneralMore Software Interview Skills 101 Pin
Dominic Burford25-May-17 6:03
professionalDominic Burford25-May-17 6:03 
GeneralSoftware Interview Skills 101 Pin
Dominic Burford12-May-17 5:44
professionalDominic Burford12-May-17 5:44 
GeneralBeat the Thrashing Pin
Dominic Burford5-May-17 6:03
professionalDominic Burford5-May-17 6:03 
GeneralWorking with Azure Blob Storage Pin
Dominic Burford27-Apr-17 2:29
professionalDominic Burford27-Apr-17 2:29 
GeneralWrestling with Apple Pin
Dominic Burford20-Apr-17 3:37
professionalDominic Burford20-Apr-17 3:37 
GeneralTwo unit tests, zero integration tests Pin
Dominic Burford10-Apr-17 22:39
professionalDominic Burford10-Apr-17 22:39 
GeneralThe Mediocre Mindset Pin
Dominic Burford29-Mar-17 1:10
professionalDominic Burford29-Mar-17 1:10 
GeneralHow much code coverage is enough? Pin
Dominic Burford21-Mar-17 5:14
professionalDominic Burford21-Mar-17 5:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.