.Net Core, QuikPub, Solo Developer

From Idea to MVP to Hacker News in 44 Hours

Unfinished side projects are the bane of a hacker’s life. How many incomplete apps are languishing in forgotten folders, 80% finished but destined never to see the light of day?

It’s the Dev equivalent of writer’s block. We love working on the interesting and the challenging parts, but it’s that final 20% that kills us. The mundane and the dull — the bits at the end that make all the difference between code that runs locally and a published app that anyone can download or use. It’s the difference between a side project and a product.

But writer’s block is not real. It’s a state of mind. The writer can choose to move past it by showing up every day. And just like the writer, the developer can choose to plow through that final 20% that leads to release day. You just have to know how close you are to the finish line.

We’re inundated with release stories that make it all look easy, and we wonder what we’re doing wrong. Version 1 of Stripe took two weeks to build. Young devs fresh out of college post to Hacker News about apps they built over the weekend. What are they doing that we’re not?

They’re releasing. Shipping. Publishing.

The idea for my latest app came to me on Saturday, January 23rd. It went live on Azure twelve days later after forty four hours of development. Two days after that I posted it to Hacker News.

This is a breakdown of how I progressed the app each day — moving one step closer to release every single day. I wasn’t burning the midnight oil. A few hours a day in between other projects. It was all very calm.

Days 1 and 2: The Idea Phase [2 hours]

My idea was to build Imgur for text. A simple and quick way for anyone to post and share rich text online — all without needing to set up a website or open an account. Rapid-fire and barrier-free publishing.

I spec’d out a list of features required for an MVP that I called Stage 1, then added a host of potential additional features that might lead to a paid plan at Stage 2 and a corporate plan at Stage 3. I don’t write code for free and consider it important that everything I build has at least the potential for turning into revenue down the road.

On Day 2 I discovered Pastebins and realised my new idea wasn’t so new after all. But I decided (rightly or wrongly) that offering rich text editing and a distraction free UI was unique enough to proceed to the development stage.

Day 3: Decisions [2 hours]

Monday afternoon I fleshed out the technology I’d be using to build the app. Choosing to use the newest and shiniest frameworks is a common mistake when devs start working on side projects. What should take one day takes five; what should be problem free becomes a can of worms as you spend more time learning and battling the technology than you do building the app.

I went with boring and simple and decided to use what I was already familiar with. .Net Core and MVC for the bones of the app with a DevExpress component I’d used before for the HTML editor, all hosted on Azure and stored in a SQL server database.

Boring and simple.

Next, I needed a catchy name and a short URL. The list below gives some indication of the direction my mind was moving before I landed on QuikPub.co. I needed a domain name that was available and global, and an app name that didn’t already have a strong Google presence (Technically .co domains are not global, but in practice they are).

Potential Names

I discounted QwikPub after finding an urban dictionary reference that suggested the word Qwik had sexual connotations in some circles, and decided against anything with Writer in the name as that was suggestive of a creative writing app rather than a publishing app. Decision made, I parked buying the domain for a couple of days in case I changed my mind.

Day 4: Building the UI [5 hours]

The core feature of the app was the rich text editor, so it had to be robust and user friendly. I decided to use a DevExpress component which was based on the Quill editor. My reasoning here was that I already had a license for their component suite, and my previous experience with DevExpress showed that support issues and questions were answered quickly — something that would come in handy on Day 10.

HTML Editor

The bulk of Day 4 was spent getting the HTML editor configured and working correctly, ensuring it was displaying the buttons I wanted it to and that everything was being posted to the backend without issue.

Day 5: The Database & the Backend [4 hours]

Nothing too difficult or complex here. I wrote a script to create the required tables in SQL Server and hooked it all up to the app using the latest version of Entity Framework in .Net Core. I was working with a local instance of SQL Server at this time as I hadn’t yet set anything up in Azure — that would all come later.

Before signing off for the day I bought the QuikPub.co domain name. One year only, as who knows if the app will be around in twelve months.

Day 6: Polishing the Backend [8 hours]

This was my only full working day on the project and it was spent putting all the pieces together and making sure they flowed correctly.

The day involved fleshing out the service and repository layers of the app, putting everything in place to allow for creating and editing QuikPubs. All very mundane and nothing any dev hasn’t done a hundred times before.

I built the View page — a light weight page that did little more than render the rich text entered by the user. It was accessible via a short URL, which was a bit tricky to get working in .Net MVC, as the usual routing recognises the short URL as an unknown controller class. I got around this by implementing a “catchall” controller action.

The Logo

By now I knew I was a few working days away from going live, so I needed to get moving on the logo design. In the past I’ve used 99designs, spending a few hundred Euro a time, but this was a rough and ready MVP that might or might not have a future so I elected to go quick and cheap with a design team over on fiverr.com.

I gave them a few examples of logos I liked along with a preferred colour scheme, paid $75 and then put it out of my mind. They had a three day turnaround which would put the logo delivery at around the time I’d be polishing the UI. Perfect.

80% Complete — The Danger Zone

This is what I call the 80% stage, when most side projects come to a halt. Everything works — kind of — but there are outstanding issues that need fixing and a lot of little things that need to be done before you can release your app.

The next few days illustrate what’s required to go from side project to product, from functional code to releasing an app. Without the next few days, all you’ve got is code, code that only you have seen and run.

If your side project was intended to be anything more than a code learning exercise, it doesn’t count until you plow through the next few days and release it.

Day 7: Page Flow [3 hours]

This was a follow on from the previous day, fixing some issues with page flow caused by the catchall routing. Once I had that fixed and working I added in a delete option so the user could delete as well as edit an existing QuikPub.

The DevExpress component suite I was using had some attractive pop-up messages built in, so I added these to the flow. By end of day everything was working and looked pretty good.

Day 8: Unique ID Generation [6 hours]

Each user post generates and stores two unique string IDs that allow viewing or editing a post. Up to now I’d been using a few made-up IDs that I’d hard coded. The time had come to automate this.

I went backwards and forwards on how to generate these IDs over the course of the day before settling on a 10 character string for viewing the post and a 32 character string (not a guid) for editing.

Decision made, I had to update the database structure and accompanying data objects, as well as make changes to the catchall controller method to route everything correctly.

Short URLs

Day 8 was a Saturday but it was raining out and we were still avoiding restaurants due to rising case numbers so I didn’t mind working. Towards the end of the day I set up the project in Azure Devops and made my first code check in. Azure Devops integration with Visual Studio is flawless, so this only took ten minutes.

Day 9: Website Theme [4 hours]

The logo arrived that morning. It was ok, but not great. I can live with it for now but if QuikPub proves to have legs I’ll have to get something more professional designed.

Logo

I picked up a bootstrap theme called Square the previous day, as one of the landing pages looked perfect for QuikPub’s home page. Up to then I’d been working with a bare bones .Net page, with the HTML editor as the sole item on the page. Now I had to flesh that out with explanatory text so that users landing on the website knew what the app was and what they could do with it.

I spent most of Day 9 getting the theme in place with its default lorem ipsum text above and below the HTML editor, and changing the css to match the colour scheme of the logo. The Publish image used at the top of the page came from DepositPhotos and cost about a euro.

Day 10 : Bug Fixing and Content Writing [5 hours]

I spent a couple of hours writing the content for the Home page that morning. Getting this right is important. If a user has to ask what your app does, then your message is failing. Clear and simple English.

I added some QuikPub examples at the bottom of the page containing blog posts I’d written and published over the past year — good enough to show what was possible with a QuickPub.

Home page

Most of the day was spent trouble shooting a jQuery issue caused by a conflict between the DevExpress components and the Square UI theme I was using for the website. Basically, none of the DevExpress components were initialising correctly, with errors popping up in the console on each page load.

I’m not a UI developer and my javascript isn’t particularly strong, so I opened a ticket with DevExpress support and sent them a sample project illustrating the problem. They came back to me within an hour with code samples showing how to initialise their components without using jQuery.

It worked. No more time wasted.

This is a perfect example of where paid-for components out perform free open source components. Try getting a one hour turnaround for support on something you’re not paying for!

Day 11: Release Day [5 hours]

I was ready to go live. Everything was working, the page content was all there, colour schemes and images were all chosen and in place. But there were a few little items that needed to be finished off, as there always are with any project just before it goes live.

I needed a small Admin area so that I could keep an eye on things in case they got out of hand. But the app had no user accounts, so how and where would I build that admin page?

I went with obscurity over security. A quick and dirty Admin page accessible via a URL that could not be guessed, coupled with a requirement for a random cookie to be pre-set in the browser. It’s not fool proof and anyone with access to the C# code in the backend could get around it by identifying the cookie, but it was good enough considering the app was not storing any private or sensitive user data or information. It took a couple of hours to put in place.

Around midday on Wednesday, 3rd of February, I created the new App Service in Azure and a new Azure SQL database. I spent about an hour trying to get Let’s Encrypt working for the app service SSL cert, all to no avail. There are a host of long form articles written about how to do this, as well as plugins to help you along, none of which worked.

Microsoft doesn’t support Let’s Encrypt out-of-the-box, so every implementation is a workaround and it looks like they break frequently. In the end I’d had enough. I wanted to launch that day, not waste any more time on Let’s Encrypt, so opted to pay for the SSL cert via Azure. It took 10 minutes and about €50 to get it all working.

The final step was to set up the support email address on the QuikPub.co domain and point it to my Fastmail account. This involved a few DNS changes and took another ten minutes. I have multiple domains feeding wildcard email addresses into a single Fastmail account — well worth the money.

I was ready to deploy.

A final code check-in with a suitably celebratory comment and I published direct from Visual Studio to my new app service. As a first deployment it took about three minutes, and the home page opened without issue.

I had a couple of problems with database access, outlined here in the first ever production QuikPub: https://quikpub.co/3K5MIPZGWP

There was one last loose end to tie up — screenshots on the home page that showed examples of short URLs , all pointing to localhost. I had to create some test posts on production and re-take those images, then re-deploy. The same with the sample QuikPub links on the home page.

And that was it. I spent half an hour testing the new app on production, then called it a day.

There was no post to Hacker News, no Twitter or blog entry, no email to my mailing list. Experience has taught me that it’s useful to let things sit for a day or two before telling the world. Something always comes up — a bug or a spelling mistake that needs fixing or a change you want to make.

Day 12: Show Hacker News

It was on Friday afternoon, February 5th, after forty four hours of development that I posted to Hacker News. For anyone unfamiliar with Hacker News, it’s THE social news site for developers. They have a Show section that allows developers or start-ups who’ve built something new to post it and talk about it on the site, where it then moves up or down the rankings in a Reddit-like fashion.

Dropbox, Stripe and many other mega start-ups began their public life on Hacker News. It’s a big deal and can lead to a lot of early exposure, feedback and page loads.

Here’s the post: https://news.ycombinator.com/item?id=26035551

QuikPub spent about a day near the top of the Show page and a similar time near the bottom of the main page. Not a spectacular result but good enough to lead to 5,000 page loads, over 600 new QuikPubs created and a host of comments on the app itself. The comments were particularly useful in tracking down and fixing HTML sanitization and css issues, while the 600 new QuikPubs helped me track down some backend bugs.

Feedback was light when it came to the functionality of the app itself, with not a lot of enthusiasm being shown. Ideally I would have liked to have seen more comments on the app and how it might be used. But that in itself is feedback, which I’ll need to ponder on.

Conclusion

There’s nothing particularly difficult about anything I did over the course of those forty four hours. Any developer with a little experience could have done the same. A strong UI developer could probably have shaved 10–15 hours off that time frame.

What makes it different from so many side projects is that it got as far as release day. By end of Day 6 most of the heavy code had been written and most of the problems had been solved. But it was those final few messy days of bug fixing, content writing, colour picking and production setup that made all the difference.

They are what made QuikPub a releasable app.


To hear more from me, you can follow me on Twitter or on LinkedIn.

.Net Core, DevExtreme, Vue.js

How to build a Vue.js application using DevExtreme UI components and a .Net Core API

I’m a backend developer with little experience of the frontend. My JavaScript skills are basic at best. A new app I’m working on requires a polished and maintainable UI, which lead me to investigate the top three frameworks of the day: React, Angular and Vue. I chose Vue as the learning curve seemed smallest, and after watching a couple of Pluralsight courses felt confident enough to make a start. [1]

DevExtreme [2] is a full JavaScript component suite from DevExpress. I’ve used DevExpress desktop components in the past and have always been impressed with the polished and professional look and feel as well as with the ease of integration and vast library of sample code. DevExtreme looks to be made in the same mold, with code samples for each component in all three frameworks mentioned above.

The sample project I’m going to walk through includes a new Vue (2.6) application using the DevExtreme Treelist component, pulling data from a .Net Core (3.1) backend API. It’s a bare bones, getting started app, with no authentication, designed to demonstrate the power of off-the-shelf components like DevExtreme and how easy it is to incorporate them into your Vue app and to populate them from a .Net Core API.

1. Creating the Vue app

The first step is to install NPM and the Vue CLI if they’re not already installed. NPM comes as part of the Node.js installation. [3] Once installed, open a terminal and run the following command to install the Vue CLI:

npm install -g @vue/cli

To create the Vue app, we’re going to use the Vue Project Manager. To launch the Project Manager, run the following command from a terminal:

vue ui

The Vue Project Manager is a simple app designed to create and manage Vue projects. It handles project creation and configuration, dependencies and plugins, and build tasks. I created my new project inside my “C:\Vue Projects” folder, and called it “Employees”.

On the presets page, choose Default Presets. We’ll start off with the basic set of dependencies and plugins and add to them later as required. Clicking Create Project will create the new project inside the selected folder. It can take a couple of minutes to complete as a large number of dependencies are downloaded and installed. Once complete, you’ll see the Project Dashboard for your new project. We’ll come back to this later.

2. Building and running your new Vue app

I’m using Visual Studio Code for my Vue apps. As a backend .Net developer I’m more familiar with Visual Studio, but find VS Code faster and easier to work with for Vue projects.

Open Visual Studio Code, select “File | Open Folder”, and browse to your “Vue Projects\Employees” folder. A new Vue project is a simple Hello World app, but all the core dependencies are in place and the project is properly configured and structured for a Single Page Application.

Open a terminal from inside VS Code (Terminal menu | New Terminal) and run the following command to install the NPM packages to the project:

npm install

If the command throws up any errors, ensure that your terminal is active in the correct folder: “C:\Vue Projects\employees”. Next, build and run the new app:

npm run serve

When the build completes without errors, you should see a local and network address for your app, in this case http://localhost:8080/.

A control + click on the link will open the app and you’ll see the default Vue Hello World application. Congratulations on your first successful, if limited, Vue app.

3. Adding the DevExtreme Treelist component

A working demo of the DevExtreme Treelist component can be found here. This includes sample Vue code and data that we’ll be using later, but for now it’s worth taking a look just to see what your new app will be displaying in place of the Hello World page.

To add DevExtreme to your project, go back to the Vue Project Manager we had open earlier and open the Dependencies section. Click on “Install Dependency” and search for “devextreme”. From the list available select and install the following three packages, one after the other: devextreme, devextreme-vue and devextreme-themebuilder.

Once installed, return to the Treelist demo page mentioned above. We’re now going to copy some code and data across to replace the Hello World project with the Treelist page code. We’ll be taking code from the App.vue, index.html and data.js pages.

First, copy the Vue code from App.vue. Go back to the project in Visual Studio Code and open the App.vue file. In the editor replace the content with the copied content from DevExtreme. Do the same for the index.html file. In your project, this file is located inside the public folder. After copying, remove the two script blocks from the bottom of the HEAD section that reference config.js and index.js.

Next, create a new file called data.js inside your project’s src folder. Copy and paste the contents of the DevExtreme data.js sample into this file.

Open a new Terminal and build and run your updated Vue app:

npm run serve

You should now see the DevExtreme TreeList demo content appearing instead what was the Vue Hello World application, as shown below. The app is fully functional, allowing you to add, edit and delete entries in the tree list, all using the predefined data source in the data.js file.

But what if we want to pull data from an API?

4. Create the .Net Core API

The next step is create a simple, bare-bones API using .Net Core 3.1 to return employee data. We’re still going to use the predefined data instead of a database, but this time that data will be accessible only from your new API.

I’m using the latest Visual Studio 2019 to create the API. Select “Create a new project” and choose “ASP.NET Core Web Application” from the list of available templates in the dialog. On the next screen, browse to your “Vue Projects” folder and name the Project “EmployeeApi”. On the Create screen, select API as the application type.

The default .Net Core app that’s created will contain some unnecessary files, so let’s remove those first. Delete the Weatherforcast.cs and WeatherForecastController.cs files. Open the launchSettings.json file inside Properties and set the launchUrl values to empty strings.

Now let’s fill out the code so that we have an endpoint to call and some data objects to send back.

First, create an empty API controller called Employee. Then add a new endpoint to it called GetEmployees and include a reference to an IWebHostEnvironment interface that you’ll need to access your data file.

Next, create your Employee object. The parameter names should be an exact match for the names in the data.js data source, as your DevExtreme Treelist expects to find these values in any data it uses.

Finally, you need to add the data source to your project. In the root project folder, create a file called data.json. Copy the data contents of the employees list in the data.js file from the Vue project into your new data.json file in the .Net Core project. This should be a Json list, not a JavaScript list, which means only copying the [ … ] block of code.

Once you’ve done this, you’re good to go. Build and run the EmployeeApi project. On my system, it’s running on https://localhost:44303/. You can test that everything is working by running a Get request to your new endpoint inside Postman, as shown below.

You’re now ready to go back to the Vue project and make the necessary changes to get the employee data from the API instead of from its own internal static data list.

5. The Vue.js app calls the .Net Core API

The first thing you need to do is go back to the Vue Project Manager and install a HTTP client so you can call your new API. As before, click “Install Dependency”, and search for and install “axios”.

Back in your Vue project, open the data.js file and delete the static list of employees. You now need to add a call to your new .Net Core endpoint, as shown below.

If your Vue app is still running, the tree list will now appear empty. This is because you haven’t updated your App.vue code to correctly call your new data access method. Replace the script section at the bottom of App.vue with the following code:

And that’s it for the Vue app. Everything should be working correctly. You’re making your call to the new API endpoint, and your Treelist should be loading the returned data.

But… it’s not.

You’re probably seeing console error messages relating to CORS and the Access-Control-Allow-Origin header. This relates to cross site scripting. Your Vue app and your API are not using the same port — something that is widely considered a security vulnerability. You can fix this by making some changes to the API. A shout out to Scott Stoecker for this.

Open the startup.cs file in the EmployeeApi project. In the ConfigureServices method, add the following line: services.AddCors();

In the Configure method, add a call to app.UseCors as shown below:

Restart the API and refresh the Treelist page in your Vue app.

You’re still not seeing data, but this time there are no console errors. Instead, you might see a DevExtreme error message telling you “The ‘ID’ key field is not found in data objects.” The solution to this can be quickly found by making the API call directly from Postman as we did earlier, and looking at the results. You should be able to see that all the variable names have been changed to camel case. DevExtreme variable names are case sensitive — it doesn’t recognise the ‘id’ field as ‘ID’.

You can fix this by making a further and final change to your startup.cs file in the .Net Core API. In ConfigureServices, adjust the call to AddControllers() as shown below:

Thanks to Ron Rebennack on Stack Overflow for that. Back in your Vue project, refresh the page and the data will now load without any console or other errors.

If you’re as new to frontend development as I am, you’ll probably agree that there are a lot of moving parts in getting even as basic a Vue app as this working and connecting to a .Net Core backend. The addition of a third party component suite like DevExtreme only adds to this, as do the changes that seem to come with every second release of .Net Core.

And that’s all without even looking at the authentication and user management that every app must have, not to mention the routing and state management required by even a moderately sized Single Page Application. Fun and games for next week.

[1] Vue.js: Big Picture, by Daniel Stern. Vue: Getting Started, by John Papa

[2] DevExtreme JavaScript component suite.

[3] Node.js installation.


To hear more from me, you can follow me on Twitter or on LinkedIn.