func explodeURL(reg rdl.TypeRegistry, r *rdl.Resource) string { path := r.Path params := "" delim := "" for _, v := range r.Inputs { k := v.Name gk := goName(string(k)) if v.PathParam { // if v.Type == "String" { path = strings.Replace(path, "{"+string(k)+"}", "\" + "+gk+" + \"", -1) } else { path = strings.Replace(path, "{"+string(k)+"}", "\" + fmt.Sprint("+gk+") + \"", -1) } } else if v.QueryParam != "" { qp := v.QueryParam item := "" if reg.IsArrayTypeName(v.Type) { item = "encodeListParam(\"" + qp + "\"," + gk + ")" } else { baseType := reg.BaseTypeName(v.Type) if v.Optional && baseType != "String" { item = "encodeOptional" + string(baseType) + "Param(\"" + qp + "\", " + gk + ")" } else { def := goLiteral(v.Default, string(baseType)) if baseType == "Enum" { def = "\"" + def + "\"" item = "encodeStringParam(\"" + qp + "\", " + gk + ".String(), " + def + ")" } else { item = "encode" + string(baseType) + "Param(\"" + qp + "\", " + strings.ToLower(string(baseType)) + "(" + gk + "), " + def + ")" } } } params += delim + item delim = ", " } } path = "\"" + path if strings.HasSuffix(path, " + \"") { path = path[0 : len(path)-4] } else { path += "\"" } if params != "" { path = path + " + encodeParams(" + params + ")" } return path }
func goHandlerBody(reg rdl.TypeRegistry, name string, r *rdl.Resource, precise bool, prefixEnums bool) string { s := "" var fargs []string bodyName := "" for _, in := range r.Inputs { name := "arg" + capitalize(string(in.Name)) if in.QueryParam != "" { qname := in.QueryParam if in.Optional || in.Default != nil { s += goParamInit(reg, qname, name, in.Type, in.Default, in.Optional, precise, prefixEnums) } else { log.Println("RDL error: queryparam must either be optional or have a default value") } fargs = append(fargs, name) } else if in.PathParam { bt := reg.BaseTypeName(in.Type) switch bt { case "Enum": s += fmt.Sprintf("\t%s := New%s(context.Params[%q])\n", name, in.Type, in.Name) case "Int32", "Int64", "Int16", "Int8": if precise { s += fmt.Sprintf("\t%s := %s(intFromString(context.Params[%q]))\n", name, in.Type, in.Name) } else { s += fmt.Sprintf("\t%s := intFromString(context.Params[%q])\n", name, in.Name) } case "Float32", "Float64": if precise { s += fmt.Sprintf("\t%s := %s(floatFromString(context.Params[%q]))\n", name, in.Type, in.Name) } else { s += fmt.Sprintf("\t%s := floatFromString(context.Params[%q])\n", name, in.Name) } default: if precise && strings.ToLower(string(in.Type)) != "string" { s += fmt.Sprintf("\t%s := %s(context.Params[%q])\n", name, in.Type, in.Name) } else { s += fmt.Sprintf("\t%s := context.Params[%q]\n", name, in.Name) } } fargs = append(fargs, name) } else if in.Header != "" { hname := in.Header def := "" if in.Default != nil { switch v := in.Default.(type) { case string: def = fmt.Sprintf("%q", v) default: panic(fmt.Sprintf("implement me, default value: %v", in)) } s += "\t" + name + "Optional := " + def + "\n" s += fmt.Sprintf("\t%s := rdl.HeaderParam(request, %q, %sOptional)\n", name, hname, name) } else if in.Optional { s += fmt.Sprintf("\t%s := rdl.OptionalHeaderParam(request, %q)\n", name, hname) } else { s += fmt.Sprintf("\t%s := rdl.HeaderParam(request, %q, \"\")\n", name, hname) } fargs = append(fargs, name) } else { bodyName = name s += "\tbody, oserr := ioutil.ReadAll(request.Body)\n" s += "\tif oserr != nil {\n" s += "\t\trdl.JSONResponse(writer, http.StatusBadRequest, rdl.ResourceError{Code: http.StatusBadRequest, Message: \"Bad request: \" + oserr.Error()})\n" s += "\t\treturn\n" s += "\t}\n" pgtype := goType(reg, in.Type, false, "", "", precise, true) s += "\tvar " + bodyName + " " + pgtype + "\n" s += "\toserr = json.Unmarshal(body, &" + bodyName + ")\n" s += "\tif oserr != nil {\n" s += "\t\trdl.JSONResponse(writer, http.StatusBadRequest, rdl.ResourceError{Code: http.StatusBadRequest, Message: \"Bad request: \" + oserr.Error()})\n" s += "\t\treturn\n" s += "\t}\n" fargs = append(fargs, bodyName) } } if r.Auth != nil { if r.Auth.Authenticate { s += authenticateTemplate } else if r.Auth.Action != "" && r.Auth.Resource != "" { resource := r.Auth.Resource i := strings.Index(resource, "{") for i >= 0 { j := strings.Index(resource[i:], "}") if j < 0 { break } j += i val := "string(arg" + capitalize(resource[i+1:j]) + ")" resource = resource[0:i] + "\" + " + val + " + \"" + resource[j+1:] i = strings.Index(resource, "{") } resource = "\"" + resource if strings.HasSuffix(resource, "+ \"") { resource = resource[0 : len(resource)-3] } else { resource = resource + "\"" } if strings.HasPrefix(resource, "\"\" + ") { resource = resource[5:] } s += fmt.Sprintf(authorizeTemplate, r.Auth.Action, resource) } else { log.Println("*** Badly formed auth spec in resource input:", r) } } methName, _ := goMethodName(reg, r, precise) sargs := "" if len(fargs) > 0 { sargs = ", " + strings.Join(fargs, ", ") } outHeaders := "" for _, v := range r.Outputs { outHeaders += ", " + string(v.Name) } noContent := r.Expected == "NO_CONTENT" && len(r.Alternatives) == 0 if noContent { s += "\terr" + outHeaders + " := adaptor.impl." + capitalize(methName) + "(context" + sargs + ")\n" } else { s += "\tdata" + outHeaders + ", err := adaptor.impl." + capitalize(methName) + "(context" + sargs + ")\n" } s += "\tif err != nil {\n" s += "\t\tswitch e := err.(type) {\n" s += "\t\tcase *rdl.ResourceError:\n" //special case the 304 response, which MUST have an etag in it for _, v := range r.Outputs { if strings.ToLower(v.Header) == "etag" { s += "\t\t\tif e.Code == 304 && " + string(v.Name) + " != \"\" {\n" s += "\t\t\t\twriter.Header().Set(\"" + v.Header + "\", " + string(v.Name) + ")\n" s += "\t\t\t}\n" break } } s += "\t\t\trdl.JSONResponse(writer, e.Code, err)\n" s += "\t\tdefault:\n" s += "\t\t\trdl.JSONResponse(writer, 500, &rdl.ResourceError{Code: 500, Message: e.Error()})\n" s += "\t\t}\n" s += "\t} else {\n" for _, v := range r.Outputs { vname := string(v.Name) if v.Optional { s += "\t\tif " + vname + " != nil {\n" s += "\t\t\twriter.Header().Set(\"" + v.Header + "\", " + vname + ")\n" s += "\t\t}\n" } else { s += "\t\twriter.Header().Set(\"" + v.Header + "\", " + vname + ")\n" } } if noContent { //other non-content responses? s += fmt.Sprintf("\t\twriter.WriteHeader(204)\n") } else { //fixme: handle alternative responses. How deos the handler pass them back? s += fmt.Sprintf("\t\trdl.JSONResponse(writer, %s, data)\n", rdl.StatusCode(r.Expected)) } s += "\t}\n" return s }