<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: André</title>
    <description>The latest articles on DEV Community by André (@redroserade).</description>
    <link>https://dev.to/redroserade</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F25931%2F04ed0a23-e26a-4289-90bf-2c50d6c4d5b9.jpg</url>
      <title>DEV Community: André</title>
      <link>https://dev.to/redroserade</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/redroserade"/>
    <language>en</language>
    <item>
      <title>Syncing Kubernetes services on MicroK8s for local development with Python</title>
      <dc:creator>André</dc:creator>
      <pubDate>Sat, 25 Apr 2020 19:18:32 +0000</pubDate>
      <link>https://dev.to/redroserade/syncing-kubernetes-services-on-microk8s-for-local-development-with-python-3lcn</link>
      <guid>https://dev.to/redroserade/syncing-kubernetes-services-on-microk8s-for-local-development-with-python-3lcn</guid>
      <description>&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This was something I did because I was bored. There are probably better ways to do this (please share them if you know any!), and your mileage most definitely will vary.&lt;/p&gt;




&lt;h1&gt;
  
  
  The situation
&lt;/h1&gt;

&lt;p&gt;Kubernetes is a common tool for deploying applications and services, and tools like Minikube or MicroK8s are great for developing applications locally with it.&lt;/p&gt;

&lt;p&gt;However, there are still situations where developing outside the cluster has its advantages. One being less overhead; not needing to sync files and directories, or attaching to remote debuggers. I like having as few layers as possible between my code and my debugger, and sometimes, even Docker development itself is a pain which I try to avoid.&lt;/p&gt;

&lt;p&gt;This, though, means that the application won't be able to access services running in the cluster by their name. This is an issue especially for me, since one of the projects I'm working on makes use of Kubernetes to dynamically provision resources, making it sometimes a pain to work with locally, and the resources all have service names I need to access.&lt;/p&gt;

&lt;p&gt;So, recently, I started researching solutions. Minikube is a good start, but since it is recommended to run it in a VM, it has too much overhead for some of the workflows I'm developing. So, I tried MicroK8s, which is great, since it runs locally, with sufficient isolation (it is installed as a Snap package on Linux). However, neither Minikube or MicroK8s have any solution to DNS "outside the cluster" (that I know of).&lt;/p&gt;

&lt;h2&gt;
  
  
  Some suggested solutions
&lt;/h2&gt;

&lt;p&gt;Usually the solution to this (at least on Linux) boils down to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run a local DNS server, or &lt;code&gt;dnsmasq&lt;/code&gt;, configured to point the service host names to your machine;&lt;/li&gt;
&lt;li&gt;Manually edit your machine's hosts file (&lt;code&gt;/etc/hosts&lt;/code&gt;) to keep things in sync yourself. For example, Minikube's &lt;a href="https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/#create-an-ingress-resource"&gt;Ingress guide&lt;/a&gt; explicitly suggests you edit your hosts file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither is great. For example, using &lt;code&gt;dnsmasq&lt;/code&gt; or a local DNS server may interfere with VPNs, meaning you may not be able to access your cluster, or your VPN's services, or both; while manually editing hosts files is a pain, and requires administrator privileges.&lt;/p&gt;

&lt;p&gt;An alternative is to use something like &lt;a href="https://www.telepresence.io/"&gt;Telepresence&lt;/a&gt; (which sounds really promising, mind), but if you're developing outside containers, it may also mess with your DNS settings in such a way that VPNs will not work either.&lt;/p&gt;

&lt;h1&gt;
  
  
  What I want
&lt;/h1&gt;

&lt;p&gt;This is what I want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be able to develop and debug my application without requiring building an image and running it in a cluster (within reason);&lt;/li&gt;
&lt;li&gt;Still be able to access the services which are deployed in the cluster by their name;&lt;/li&gt;
&lt;li&gt;Not mess up the VPNs I need to access enterprise resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since DNS is out of the question, I'm left with hosts files, so I'll use those.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hosts files
&lt;/h2&gt;

&lt;p&gt;A hosts file, briefly, is a text file containing a "table" of IP Address to Host Name(s), like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;127.0.0.1 localhost
192.168.1.1 my-router
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;These files exist on Windows, macOS, and Linux, and once updated, they will be used for host name resolution, instead of your DNS server (note that there are exceptions to this, which I'll not cover here).&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Kubernetes Services
&lt;/h2&gt;

&lt;p&gt;There are several ways of exposing a Deployment's containers with a &lt;code&gt;Service&lt;/code&gt;. Here are some:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NodePort&lt;/code&gt;, which maps a port on the host to the port on the container (much like port forwarding, or the &lt;code&gt;-p&lt;/code&gt; option for &lt;code&gt;docker run&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ClusterIP&lt;/code&gt;, which assigns a cluster-local IP Address for that Deployment&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LoadBalancer&lt;/code&gt;, which allows routing to multiple replicas of a Deployment's pods to distribute load.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's also &lt;code&gt;Ingress&lt;/code&gt; resources, which you can use to expose &lt;code&gt;Service&lt;/code&gt;s outside the cluster as specific host names. You should preferably use these if you want to expose services to the outside.&lt;/p&gt;

&lt;h1&gt;
  
  
  Demonstrating the problem
&lt;/h1&gt;

&lt;p&gt;Assume you have an Nginx web server you want to expose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl create deployment nginx --image nginx
deployment.apps/nginx created
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will create a deployment and a Pod for Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get pods
NAME                                         READY   STATUS      RESTARTS   AGE
nginx-f89759699-2thhf                        1/1     Running     2          7h3m
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To expose this deployment's Pods (to the cluster's pods and to the outside), we need a Service. We can create one like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl expose deploy nginx --port 80 --name nginx-svc
service/nginx-svc exposed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can now check that it was created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get services
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
nginx-svc    ClusterIP   10.152.183.235   &amp;lt;none&amp;gt;        80/TCP    39s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you type that IP Address (note that it will be different in your case), you should see the Nginx welcome page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl 10.152.183.235
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Welcome to nginx!&amp;lt;/title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, the same &lt;code&gt;nginx-svc&lt;/code&gt; is available to other Pods on the clusters via its name. You can test this by running another Pod on the cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl run -i -t --rm --image alpine name
If you don't see a command prompt, try pressing enter.
/ # apk add curl
&amp;lt;snip&amp;gt;
/ # curl nginx-svc
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Welcome to nginx!&amp;lt;/title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But if you do it outside the Cluster (i.e., on the host):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl nginx-svc
curl: (6) Could not resolve host: nginx-svc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It fails, as there is no DNS entry for the service name outside the cluster.&lt;/p&gt;

&lt;h1&gt;
  
  
  The solution
&lt;/h1&gt;

&lt;p&gt;If you add the IP address of the service to the hosts file, it will work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ echo '10.152.183.235 nginx-svc' | sudo tee /etc/hosts
10.152.183.235 nginx-svc
$ curl nginx-svc
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Welcome to nginx!&amp;lt;/title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Mind that this works because MicroK8s sets up a network interface and routes to allow traffic from your host machine to the cluster, and vice versa.&lt;/p&gt;

&lt;p&gt;Anyway, this is great, but it means that I need to edit the hosts file manually. That's boring, so let's automate this:&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating hosts file synchronization
&lt;/h2&gt;

&lt;p&gt;We need two things for each service: it's name, and it's IP address inside the cluster. I could use &lt;code&gt;kubectl&lt;/code&gt; and Shell Scripts to retrieve the information I need, but I decided to resort to Python instead. This also allows me to use the &lt;code&gt;kubernetes&lt;/code&gt; library. This can be installed with &lt;code&gt;pip&lt;/code&gt;. After that, we can do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kubernetes.config&lt;/span&gt;

&lt;span class="c1"&gt;# The first thing we need to do is configure the library with our credentials. This will load them from ~/.kube/config.
&lt;/span&gt;&lt;span class="n"&gt;kubernetes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_kube_config&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;core&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kubernetes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CoreV1Api&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Get the services from the server (I'll assume the default namespace)
&lt;/span&gt;&lt;span class="n"&gt;services&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_namespaced_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;f"Service &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; has IP &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cluster_ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Running this, we get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service kubernetes has IP 10.152.183.1
Service nginx-svc has IP 10.152.183.235
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's a good start! Now, we need to add this information to the hosts file. I'll do this in a very naive way to keep things simple, so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kubernetes.config&lt;/span&gt;

&lt;span class="c1"&gt;# The first thing we need to do is configure the library with our credentials. This will load them from ~/.kube/config.
&lt;/span&gt;&lt;span class="n"&gt;kubernetes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_kube_config&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;core&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kubernetes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CoreV1Api&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Get the services from the server (I'll assume the default namespace)
&lt;/span&gt;&lt;span class="n"&gt;services&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_namespaced_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;

&lt;span class="c1"&gt;# Open the hosts file in append mode, so that we can write to it.
# ATTENTION: DO NOT RUN THIS, IT MIGHT DAMAGE YOUR HOSTS FILE!
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/etc/hosts'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;hosts_writer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Write an empty line, in case the file doesn't end with a new line (in case you do run this)
&lt;/span&gt;    &lt;span class="n"&gt;hosts_writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="si"&gt;\&lt;/span&gt;&lt;span class="se"&gt;n&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# The format of the hosts file is [IP] [Host Name], so we can write to it like this:
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;hosts_writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;f'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cluster_ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Again, &lt;strong&gt;do not run this&lt;/strong&gt;! You might damage your hosts file, which can cause you trouble.&lt;/p&gt;

&lt;p&gt;But, assuming you do manage to run this (&lt;code&gt;sudo&lt;/code&gt; kind of breaks things with Kubernetes, thankfully), your hosts file should be updated. However, if you did manage to run this, do not run this repeatedly, as this will keep appending new lines to the hosts file. &lt;/p&gt;

&lt;p&gt;To make this a bit safer, you could perhaps make the script mark added lines with a comment, and then remove them before adding new ones.&lt;/p&gt;

&lt;h1&gt;
  
  
  Going further
&lt;/h1&gt;

&lt;p&gt;Having the basic version of the script, we can go a bit further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add support for Ingress resources, such that they are also accessible from the host (if they have a defined host, of course);&lt;/li&gt;
&lt;li&gt;Running this periodically in the Cluster, with a Cron job;&lt;/li&gt;
&lt;li&gt;Extra validation checks for sanity;&lt;/li&gt;
&lt;li&gt;Add filters such that we only expose some hosts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can check what I did at this &lt;a href="https://github.com/RedRoserade/microk8s-sync-hosts"&gt;GitHub Repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>microk8s</category>
      <category>python</category>
    </item>
    <item>
      <title>I'm going to be a teaching assistant, teaching web technlogogies. What should I know?</title>
      <dc:creator>André</dc:creator>
      <pubDate>Wed, 24 Jan 2018 22:37:34 +0000</pubDate>
      <link>https://dev.to/redroserade/im-going-to-be-a-teaching-assistant-teaching-web-technlogogies-what-should-i-know-48g3</link>
      <guid>https://dev.to/redroserade/im-going-to-be-a-teaching-assistant-teaching-web-technlogogies-what-should-i-know-48g3</guid>
      <description>&lt;p&gt;Hello!&lt;/p&gt;

&lt;p&gt;(Note: this may be quite long, but I appreciate your feedback)&lt;/p&gt;

&lt;p&gt;As you might have read from the title, I've been recently invited by my polytechnic institute to help assist them in lecturing the classes for the "Internet Technologies II" course. To give some backstory about this course (and the degree it's a part of), it's the second course (of two) that's directly related with web technologies.&lt;/p&gt;

&lt;p&gt;The first course focuses mainly on the 3 'pillars' of front-end web development: HTML, CSS, and JavaScript, and things like DOM manipulation, events and querying.&lt;br&gt;
It then moves on to jQuery and Bootstrap, explaining the things that can be done with them. &lt;br&gt;
Finally, a brief introduction to Canvas and SVG (+ XML with JavaScript) is done, whose objective is more to develop the thought process, than the actual need to use these technologies directly.&lt;br&gt;
The students are evaluated with a project that consists in a purely client-side application, usually sort of a "toolkit", with many "apps" that use the concepts lectured through the course (for example, a calculator, or a clock made with Canvas, or a color picker, or something like a calendar).&lt;/p&gt;

&lt;p&gt;Not much is lectured about layout, when I attended the course, the only aspects that were lectured were table layouts and absolute positioning. I think that this has changed, but I haven't yet been able to talk to the professor to know more about this.&lt;/p&gt;

&lt;p&gt;The second course (which is the one I'm going to help with) focuses on the back-end. Due to our partnership with Microsoft, and the market in Portugal, we focus on ASP.NET MVC (up to a few years ago, it was pure WebForms, but it changed due to the altering landscape).&lt;br&gt;
Although I prefer to work with Node.js, I do agree that ASP.NET MVC is a good choice for the web framework to teach. It's powerful, well-structured, and well-documented. The objective of the course is to teach the students how to combine the contents of the first course, and combine them with the concepts of back-end routing to controllers and views, introducing models and CRUD concepts with Entity Framework and SQL Server, and finally, authentication and authorization.&lt;br&gt;
Since this course is lectured by two different teachers, the back-end part only represents 2/3 of the hours of the course. The remaining third focuses on technologies such as JSON and AJAX (which are still fetched using ActiveX because the teacher doesn't set up a static file server), and more advanced DOM concepts.&lt;br&gt;
In this course, the students have two projects: One focuses on the ASP.NET part, the other focuses on building an app that uses the remainder of the technologies lectured on the last third.&lt;/p&gt;

&lt;p&gt;We only have about 14 weeks, each having 2 classes (a 2-hour one and a 3-hour one). Some classes are used for presentations, where the students present to the class what they've been working on, and so that possible mistakes can be caught early on (for example, making an "online store" application, but there is no support to save pictures for the products). In total, we have about 11-12 weeks that are used for actual lectures. This, times 5 hours a week, gives us a total of about 50-60 course hours, spread over a semester.&lt;/p&gt;

&lt;p&gt;Knowing this, I think that the concepts taught on the 2-hour classes could be moved to the first course (perhaps in detriment of Canvas and SVG?), but perhaps for this year I'll leave them as-is (I'll use proper APIs though, not ActiveX).&lt;/p&gt;

&lt;p&gt;Here are my ideas for this course:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I've worked with some students that graduated from this school, and they often don't know much about layout. I should introduce them to the positioning methods, Floats, Flexbox, and ideally, CSS Grids. Media Queries are also a good idea, I often find that they don't know how Bootstrap works.&lt;/li&gt;
&lt;li&gt;I think that introducing them not just to get data using AJAX, I also want to show them how they can submit data with it. Perhaps I should show them Fetch? It's still not standardized as far as I know, but Promises are pretty much everywhere now, and perhaps this is a good proxy to introduce them.&lt;/li&gt;
&lt;li&gt;Note that I must be careful not to introduce things that are too bleeding-edge, the harsh reality is that most enterprise clients in Portugal still use old versions of IE.&lt;/li&gt;
&lt;li&gt;I often find that people don't know how to use the browser's Developer Tools. Perhaps I should show them how they work? Work with them in debugging the DOM, CSS, and JavaScript, in an app that's deliberately buggy?&lt;/li&gt;
&lt;li&gt;I also want to show them some "intermediate" concepts of JavaScript. Sadly, on the first course, not much is taught, and some features are dubious at best (read: &lt;code&gt;with&lt;/code&gt;). Thinks like Arrow Functions, new APIs (which?), and perhaps, Classes (they come with a Java background to this course).&lt;/li&gt;
&lt;li&gt;Depending on how things evolve, I want to transition to the back-end, so that the topics can be taught with more time and detail, because there isn't much time to explain all the concepts of ASP.NET in ~30 hours. I'd like to go further into things like model/form validation, the basics of RESTful APIs, and going further into authorization, like returning subsets of data based on the user's privileges.&lt;/li&gt;
&lt;li&gt;I think that the two projects should be merged into one.&lt;/li&gt;
&lt;li&gt;Should I, if I had the time, show them the client-side frameworks that are "hot" right now? React, for example, is gaining a lot of traction in Portugal's enterprises.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having read this (thanks!), is there anything you would change? I know that there is much that could be changed, but such things must be done one thing at a time. I'd also like to know what your recommendations are when it comes to lecturing classes. &lt;br&gt;
I am well aware that knowing about the subject is sometimes not enough for us to be able to teach about it in an effective way, so how would you go about it, if you were doing it?&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
