Here is a possibility:
\documentclass{article}
\usepackage{xparse,tikz}
\usetikzlibrary{positioning,calc}
\NewDocumentCommand{\compoDiagram}{o m m m m m}{%
\begin{tikzpicture}[baseline=-0.5ex, on grid, node distance=1.5cm]
\node (diagraminit) {#2};
\node[draw,right of=diagraminit] (func1) {#3};
\node[right= 2cm of func1] (diagrammid) {#4};
\node[draw,right= 2cm of diagrammid] (func2) {#5};
\node[right= 3cm of func2] (diagramend) {#6};
\draw[-] (diagraminit)--(func1);
\draw[-latex] (func1)--(diagrammid);
\draw[-] (diagrammid)--(func2);
\draw[-latex] (func2)--(diagramend);
\IfNoValueTF{#1}{%true
}
{
\node[draw] (diagramcomposition) at ($(diagraminit)!0.5!(diagramend)-(0,1)$){#1};
\draw[-latex](diagraminit)|-(diagramcomposition)-|(diagramend);
}
\end{tikzpicture}
}
\begin{document}
\compoDiagram[$G \circ F$]{$x$}{$F$}{$y=F(x)$}{$G$}{$z=G(y)=G \circ F(x)$}
\vspace{2cm}
\compoDiagram{$x$}{$F$}{$y=F(x)$}{$G$}{$z=G(y)=G \circ F(x)$}
\end{document}
Result:

Beware: the node distances are optimized for this kind of inputs (in terms of node width).
Since the basic use is in math mode, perhaps is it is boring typing $ inside the \compoDiagram each time; it is for sure better:
\compoDiagram[G \circ F]{x}{F}{y=F(x)}{G}{z=G(y)=G \circ F(x)}
Thus, a possible modification of the command is:
\NewDocumentCommand{\compoDiagram}{o m m m m m}{%
\begin{tikzpicture}[baseline=-0.5ex, on grid, node distance=1.5cm]
\node (diagraminit) {\ensuremath{#2}};
\node[draw,right of=diagraminit] (func1) {\ensuremath{#3}};
\node[right= 2cm of func1] (diagrammid) {\ensuremath{#4}};
\node[draw,right= 2cm of diagrammid] (func2) {\ensuremath{#5}};
\node[right= 3cm of func2] (diagramend) {\ensuremath{#6}};
\draw[-] (diagraminit)--(func1);
\draw[-latex] (func1)--(diagrammid);
\draw[-] (diagrammid)--(func2);
\draw[-latex] (func2)--(diagramend);
\IfNoValueTF{#1}{%true
}
{
\node[draw] (diagramcomposition) at ($(diagraminit)!0.5!(diagramend)-(0,1)$){\ensuremath{#1}};
\draw[-latex](diagraminit)|-(diagramcomposition)-|(diagramend);
}
\end{tikzpicture}
}