Jekyll2022-06-19T18:43:46+00:00https://schneierscode.com/atom.xmlSchneidersCodeMason SchneiderExplaining Software Engineering with the Classic PB&J Problem2022-06-19T00:00:00+00:002022-06-19T00:00:00+00:00https://schneierscode.com/technology/education/2022/06/19/explain-software-engineering-with-pbj<h2 id="the-common-pbj-problem">The Common PB&J Problem</h2>
<p>I’m sure we’ve all seen the common challenge given to students - <a href="https://www.youtube.com/watch?v=HXl5f2azATU">“Write instructions to make a peanut butter and jelly sandwich.”</a> Almost always, the students give some vague step or imprecise instruction and the instruction follower ends up doing something the student didn’t intend to happen. I think there’s definitely some weak spots in this example but showing students the step-by-step example of programming to achieve a goal holds well.</p>
<h2 id="extending-this-to-software-engineering">Extending this to Software Engineering</h2>
<p>Recently, I was thinking of ways to explain what software engineers do to family and friends and I came back to this programming introduction. At its base, the PB&J problem is a good way to explain “coding” and I believe we can extend this to exemplify common challenges software engineers face. We can start with a simple idea of loops, conditions, and failures and then we can even extend this to a scaling and grouping challenge. I think these extensions are great tools to explain more of the common complexities we face in our jobs.</p>
<p>If I’m explaining software engineering to someone who has heard of or done the PB&J challenge I try to add new complexities in layers. This helps people appreciate how problems can grow, complexities increase, and requirements change. I also find that older children and teens that find these extensions interesting and hard are usually the same ones who may really enjoy software engineering.</p>
<h3 id="student-list---loops-and-conditions">Student List - Loops and Conditions</h3>
<p>The first extension is to take your PB&J function and think about how to use it to build PB&Js for the entire class. Will we just make one sandwich for how many people are in the class? What about absent students? Do we track who has gotten one so students can’t ask for another?</p>
<p>These ideas demonstrate the complexities of looping, edge cases, and conditions. I think it’s a great example of taking something like a “hacky” bash script and making it a little more dynamic to automate some menial task in your job. Someone who sees how this grows the challenge of the PB&J instruction are likely people who will also sink their teeth into programming quickly.</p>
<h3 id="jelly-preferences---dynamic-fields-and-errors">Jelly Preferences - Dynamic Fields and Errors</h3>
<p>Now that we’ve explored the idea of lists and conditions we can extend this challenge further. Suppose we have three jelly flavors (strawberry, grape, and blackberry). We have a list of what each student has written in as their chosen jelly and we need to modify our PB&J algorithm to support these jelly type selections. Is it easier if we make all of one type of jelly at a time? Do we need to check if that student is in class today before making their preferred jelly sandwich? What about the naughty student who wrote “chocolate” as their jelly choice? Do our brains explode or do we gracefully choose a default like strawberry? What happens if we add a new jelly or run out of one?</p>
<p>This modification to the challenge helps show how a software engineer needs to handle dynamic input and foresee problems that might happen. It illustrates how software can break and how engineers need to create fault tolerant, dynamic solutions. I think that people who pick up on these edges are great candidates for software engineers.</p>
<h3 id="school-cafeteria---scaling-and-databases">School Cafeteria - Scaling and Databases</h3>
<p>Our PB&J maker is now catching on in popularity and the school wants to use it in all classes. We need to further extend our instructions on how to get the student list and preferences from each classroom, determine the order to make them in, and make sure the correct sandwich counts get back to each classroom. Will students changing preferences between days cause issues? How can you write instructions for different people so that some can collect attendance and preferences while others make sandwiches?</p>
<p>This data lookup, grouping, and attributing is a great example of simple database interactions and how to consider scaling in a problem. I think that this extension is the best place for students and instructors to run wild with the possibilities of making the processes as fast as possible. Thinking about ways to scale this gets the engineering cogs turning.</p>
<h2 id="potential-software-engineers">Potential Software Engineers</h2>
<p>From these modifications students should start to see where the real complexities of software engineering come from. It’s not always writing a simple instruction but rather the dynamic and ever changing requirements that make being a software engineer challenging and exciting. I believe that the people who grasp these complexities and can foresee how one might run into issues with them are the same people who may really latch on to software engineering. It really almost feels like a litmus test for software engineers.</p>Mason SchneiderThe Common PB&J ProblemVue with low-code GraphQL2020-05-30T00:00:00+00:002020-05-29T00:00:00+00:00https://schneierscode.com/technology/guides/2020/05/30/vue-hasura-auth0-apollo<h2 id="using-hasura-and-auth0-with-vue">Using Hasura and Auth0 with Vue</h2>
<p>If you’re not familiar with <a href="https://hasura.io/">Hasura</a>, it’s a low-code offering that provides a full GraphQL endpoint with an easy-to-use UI for defining data models, relationships, and permissions. Combined with <a href="https://auth0.com/">Auth0</a>, a managed authentication offering, Hasura can provide full authentication and authorization models with JWT tokens. With these two offerings we have everything we need for backend management. Creating a simple frontend with Vue means we can spin up full-stack applications in record time. This setup has let me spend more time focusing on features for users.</p>
<p>Both Hasura and Auth0 have stellar basic walkthough documentation so much of this will defer to those guides. The point of this post will be to cover specific issues I hit in this stack model and how to use the provided template to overcome these problems.</p>
<h2 id="template-example-for-this-guide">Template example for this guide</h2>
<p>Code references and setup can be found <a href="https://github.com/MasonSchneider/Vue-GraphQL-Template">in the example template repo</a>. This is a great source for starting out a new Vue+GraphQL project. The rest of this post will cover getting to this setup and the configuration required to make it work.</p>
<h2 id="hasura-setup">Hasura Setup</h2>
<h3 id="hasura-instance">Hasura Instance</h3>
<p>The easiest setup is <a href="https://hasura.io/docs/1.0/graphql/manual/getting-started/heroku-simple.html">launching Hasura on Heroku</a>. Once you have the instance up, be sure to create <a href="https://hasura.io/docs/1.0/graphql/manual/deployment/heroku/securing-graphql-endpoint.html">an Admin secret</a> for security (you’ll need this later).</p>
<h3 id="users-table">Users Table</h3>
<p>In order to track users to grant users permissions to their data we need to create a table that tracks registered users from Auth0. To do this, we’ll need to <a href="https://hasura.io/docs/1.0/graphql/manual/getting-started/first-graphql-query.html#create-a-table">create a ‘users’ table</a> with at least an ‘id’ field that is text and a Primary Key of the table.</p>
<p><img src="/assets/images/screenshotUsersTable.png" alt="Create Users snapshot" /></p>
<h2 id="auth0-setup">Auth0 Setup</h2>
<h3 id="hasura-integration">Hasura Integration</h3>
<p>Hasura provides <a href="https://hasura.io/docs/1.0/graphql/manual/guides/integrations/auth0-jwt.html#guides-auth0-jwt">an excellent guide</a> for getting started with Auth0 JWT tokens for authentication. Once you’ve completed the steps here some minor QoL tweaks are needed to have full integration.</p>
<h3 id="hasura-permissions">Hasura Permissions</h3>
<p>Once your Auth0 rule is inserting User IDs into your users table and attaching the X-Hasura-User-ID, authorization can be configured. The <a href="https://hasura.io/docs/1.0/graphql/manual/auth/authorization/index.html">authorization guide</a> is straightforward but it’s important to note the columns field needs to be set as well as the row access.</p>
<h3 id="auth0-vue-integration">Auth0 Vue Integration</h3>
<p>Auth0 gives a good <a href="https://auth0.com/docs/quickstart/spa/vuejs/01-login">initial setup guide</a> but <a href="https://github.com/MasonSchneider/Vue-GraphQL-Template/tree/master/src/auth">I’ve made tweaks</a> to better support Apollo.</p>
<p>The main difference is that rather than creating the auth client on the side, my app creates it as <a href="https://github.com/MasonSchneider/Vue-GraphQL-Template/blob/master/src/main.js">a blocking step in main</a>. It also sets the response_type to token_id so that <code class="language-plaintext highlighter-rouge">getTokenSilently()</code> returns a JWT token that can be sent to Hasura. With this, Apollo can create a function link without using a local storage of the JWT which is a security risk noted by Auth0.</p>
<h2 id="apollo-configuration">Apollo Configuration</h2>
<p>As mentioned above, the entire <a href="https://github.com/MasonSchneider/Vue-GraphQL-Template/blob/master/src/main.js#L78">Apollo provider creation</a> is blocked on Auth0 initializing. Without this I saw race conditions where the first Apollo call would fail from bad tokens but following calls would succeed because the tokens were then loaded and ready.</p>
<h3 id="apollo-graphql-query-to-hasura">Apollo GraphQL query to Hasura</h3>
<p>Now that your user is authorized, identified, and tokens are loaded you can use Apollo to query your Hasura endpoint. This leads to a <a href="https://github.com/MasonSchneider/Vue-GraphQL-Template/blob/master/src/views/Home.vue">super simple data model</a>. With this pattern I’ve found myself spending a lot less time on wiring and more time on building.</p>
<h2 id="common-mistakes">Common Mistakes</h2>
<h3 id="hasura-permissions-not-including-columns">Hasura permissions not including columns</h3>
<p>If you’re seeing <code class="language-plaintext highlighter-rouge">field 'x' not found in type: 'y'</code> and you’re certain the field does exist it’s likely permissions.</p>
<ol>
<li>
<p>Go to the Hasura permisisons page for the table of the failing type
<img src="/assets/images/permissionsScreenshot.png" alt="Permissions snapshot" /></p>
</li>
<li>
<p>Expand the role of the failing call and view allowed columns
<img src="/assets/images/screenshotColumns.png" alt="Column snapshot" /></p>
</li>
<li>
<p>Enable the columns your query needs access to in that role</p>
</li>
</ol>
<h3 id="auth0-login-on-page-refresh">Auth0 login on page refresh</h3>
<p>If you custom rolled your auth0 client initialization you’ll need to directly check for a current user session. However, if you’re using the built in auth0 initializer then your client already pulls some cached login values for you so this isn’t the issue.</p>
<p>My fix was <a href="https://auth0.com/docs/connections/social/google">using a personal Google API token</a> rather than the Auth0 provided token for logins.</p>
<h3 id="first-apollo-query-fails-with-bad-credentials">First Apollo query fails with bad credentials</h3>
<p>The Apollo Configuration section explains the need for wrapping the Apollo link header code in a wait on the Auth0 client. Essentially, Apollo and Auth0 examples usually load side-by-side using localstorage tokens that can time out. My fix was to wait until we’ve done an initial population of the user session before configuring Apollo and doing our first query.</p>Mason SchneiderUsing Hasura and Auth0 with VueHello World!2019-10-21T00:00:00+00:002019-10-21T00:00:00+00:00https://schneierscode.com/personal/2019/10/21/hello-world<h1 id="blog-40">Blog 4.0</h1>
<p>I’ve started a few blogs/personal websites in the past. They’ve always been something I’ve home brewed.</p>
<h2 id="my-first-try">My First Try</h2>
<p>My first attempt was a personal site in PHP ridden with the classic PHP vulnerabilities. I even rolled my own “crypto”!
I went all out with it. I created a CMS style admin panel and even created a mailing list. What a nice and fun time it was, not worrying about SQL injections or setting up SSL.</p>
<h2 id="try-two">Try Two</h2>
<p>My second attempt I decided I should show off my great javascript ability and UX expertise /s. I made a terminal emulator with the classic “Matrix” green. I can’t imagine pointing a recruiter to that site. It was also very prescriptive in the available commands, so if you weren’t a fan of “less” then you had no hope of reading what I had to say.</p>
<h2 id="static-is-good">Static is good</h2>
<p>From there I decided I should remove the fancy UI and go with something more minimal. I spun up my THIRD custom built website. This one was “static” but relied on a json file of blog data to dynamically populate blog posts. Although it was functional, it lacked any real feel and I was afraid to touch it.</p>
<h2 id="this-attempt">This attempt</h2>
<p>I finally decided I was done rolling my own. So here I am, using <a href="https://jekyllrb.com/">Jekyll</a>. It was a much larger pain to setup than I had expected (blog post to come). I think that, although the overhead setup seems to have been about the same amount as previous sites, the final outcome has left me with a pretty easy to modify blog and landing page.</p>
<h2 id="and-more">And more?</h2>
<p>Hopefully I stay happy with my setup but with all the cool tools and toys, how can I resist changing my setup again? Because these posts will be in markdown, they’ll be easier to migrate compared to earlier iterations so hopefully even if I do move I’ve future proofed a little better than before.</p>
<h2 id="future-blogs">Future Blogs</h2>
<p>So here’s to Blog 4.0! Hopefully you’ll find something fun to read and I’ll find something fun to write.</p>Mason SchneiderBlog 4.0