Ejemplo n.º 1
0
// GenerateResourceDefinition produces the JSON schema corresponding to the given API resource.
// It stores the results in cachedSchema.
func GenerateResourceDefinition(api *design.APIDefinition, r *design.ResourceDefinition) {
	s := NewJSONSchema()
	s.Description = r.Description
	s.Type = JSONObject
	s.Title = r.Name
	Definitions[r.Name] = s
	if mt, ok := api.MediaTypes[r.MediaType]; ok {
		buildMediaTypeSchema(api, mt, s)
	}
	for _, a := range r.Actions {
		var requestSchema *JSONSchema
		if a.Payload != nil {
			requestSchema = TypeSchema(api, a.Payload)
			requestSchema.Description = a.Name + " payload"
		}
		if a.Params != nil {
			params := a.Params.Dup()
			// We don't want to keep the path params, these are defined inline in the href
			for _, r := range a.Routes {
				for _, p := range r.Params() {
					delete(params.Type.ToObject(), p)
				}
			}
		}
		var targetSchema *JSONSchema
		var identifier string
		for _, resp := range a.Responses {
			if mt, ok := api.MediaTypes[resp.MediaType]; ok {
				if identifier == "" {
					identifier = mt.Identifier
				} else {
					identifier = ""
				}
				if targetSchema == nil {
					targetSchema = TypeSchema(api, mt)
				} else if targetSchema.AnyOf == nil {
					firstSchema := targetSchema
					targetSchema = NewJSONSchema()
					targetSchema.AnyOf = []*JSONSchema{firstSchema, TypeSchema(api, mt)}
				} else {
					targetSchema.AnyOf = append(targetSchema.AnyOf, TypeSchema(api, mt))
				}
			}
		}
		for i, r := range a.Routes {
			link := JSONLink{
				Title:        a.Name,
				Rel:          a.Name,
				Href:         toSchemaHref(api, r),
				Method:       r.Verb,
				Schema:       requestSchema,
				TargetSchema: targetSchema,
				MediaType:    identifier,
			}
			if i == 0 {
				if ca := a.Parent.CanonicalAction(); ca != nil {
					if ca.Name == a.Name {
						link.Rel = "self"
					}
				}
			}
			s.Links = append(s.Links, &link)
		}
	}
}