So, here's the obligatory "it's been a while" line. I haven't posted to this blog in a few months, but, it's for good reason, really. See, I look at this way. My last blog post was about building something. And, that's just what I did. I completed my latest startup: Gear Offer. It's a marketplace where you can buy and sell used camera gear online. You might ask yourself, doesn't such a marketplace already exist? The answer is no. Not until now. But, you didn't come hear to learn about my startup, you came here to find out about the tech stack.
A Bit of History
The idea for this startup began a few years ago, but I only started writing the web app in March of 2017. At the time, .Net Core was a little primitive and it was changing fast. I figured it was worth the risk to try out with a project like this and now, I'm really, really glad I took that risk.
As with any new technology that's fast-changing, there was some pain involved. Mostly when it came to documentation and solving problems. Because the technology changed so much, getting answers on how to do things was sometimes hard. I would come across examples for doing things that applied to .Net Core 1.x but not 2.x. But, it really wasn't that bad. Now, the platform is much more stable and it's easy to get answers.
Most .Net developers go the standard route with data storage and use SQL Server and Entity Framework. I'm not a fan of EF and wanted to avoid SQL Server for various reasons. Instead, I chose to use PostgreSQL as a document database with Marten in the middle. Yet another decision that I'm very happy with. Getting used to storing documents took some time, but for my use, it makes sense and works quite well.
Let's Talk Performance First
This is what I feel like everyone will want to know about: how is the performance? It's really, really fast. As of .Net Core 2.1, I'm blown away by the speed of my web app. This wasn't always the case. With .Net Core 2.0 and with previous versions, performance was okay during development, but it wasn't mind-blowing. Now, I'm not running benchmarks and my site is not heavily used at this point, but the page load times are pretty impressive.
I'm hosting the site using Azure App Service, Azure's Postgre option, Azure Blob Storage and Application Insights is monitoring everything. I really like using Azure and getting things setup was pretty straight forward. The one thing that was tricky was setting up SSL using Let's Encrypt but this awesome blog post by Troy Hunt got me through it. Now, I have an Azure Web Job running that updates my certificate every 3 months.
This setup isn't cheap. I get some credits for having an MSDN subscription, but even with that I'll still be shelling out some cash. Currently, I'm looking about a total of $200 per month to run this app. That's not bad, but it's also got no traffic right now so we'll see how high that bill goes if and when things start moving. Also, a quick note about Application Insights: at first, I wasn't sure I was going to bother using it, but now I'm really glad I did. On more than one occasion, it's saved my ass with production bugs and it's super-cheap so that's good.
This web app is fairly complex. It handles financial transaction, all sorts of notifications and communications between users. Below are some of the API's that it interacts with.
I decided to use Auth0 for identity management. Knowing that I'm not in charge of hashing or storing passwords is truly nice. Auth0 has some great API's and good documentation as well. They give you up to 7000 active users for free, which is quite generous. If I go beyond 7000 active users, I better be making some money and can afford their higher paid plans.
Because my app is a marketplace, I decided to use Stripe Connect using Custom Accounts. This means that my use of Stripe is completely transparent to my users. It also means that I have to custom build a lot of account management functionality. But, like Auth0, Stripe has great API's and documentation. Also, their developer support is truly awesome.
For example, I had a question late on a Saturday night. I submitted my question on their support site and expected a response in a few days. Sunday morning I got a call from a Stripe developer support rep. This person knew their stuff and was able to answer my question and suggest a few solutions. I was blown away by that. That kind of service just doesn't happen these days. Yeah, Stripe's pretty rad.
The story here is just okay. SendGrid does a great job of handling transactional emails. Their campaign/email list functionality is not so great. It feels tacked on and I ended up ditching it for another provider when it comes to campaigns. Also, I started out using a cheap $10 per month shared IP plan that worked out well for a while. Then my email reputation score dropped to a staggering %19.
Turns out these shared IP plans can really hurt your deliverability because some other schmuck using a SendGrid account that's on the same IP is spaming people. Of course, the solution is to spend more money. Now I have my own IP address, but I'm also paying $80 per month. Not happy about that, but email deliverability is crucial to my app because that's how I notify users that their gear sold or that they have a new inquiry, etc.
A lot of code was written to build this app, but I knew I didn't want to mess with writing my own CMS. I needed the ability to create content for marketing and information about the app. I looked into several headless CMS platforms and ended up using Prismic. Their free plan is very generous. In fact, I'm probably going to start paying the $7 per month they charge for additional users just because I like it so much.
They have a .Net API client that's not well documented, but I was able to figure it out. Now I have a blog and tons of pages integrated into my app and I only had to create one MVC controller for the blog and one for the pages. Using the slugs in the URL of my posts and pages, I pull the content from Prismic and the content magically appears. I love that. If I build a Xamarin app for this marketplace, I can use the same content.
Every app that ships physical products should have shipping tracking built in. It's just expected. I ended up using EasyPost because their documentation was good and, you guessed it, they have a nice .Net API client. Also, at $0.1 per tracker, it's an affordable option.
As with any startup, I have no idea if this marketplace of mine will succeed. They say starting a two-sided marketplace is nearly impossible and that's proving to be true currently. But, if this product does have legs, I'll be building an app for it using Xamarin forms. I'll write about that experience if that time comes.
I'm really glad I chose to use .Net Core and Marten. The performance is amazing and Azure has been great so far. If you're looking to build something, I recommend these technologies. From my experience so far, I'm really happy. Now I just have to learn to become a better marketer and solve the chicken and egg problem with this marketplace.