Documentation
¶
Overview ¶
Package radarapi provides bindings for the radar.squat.net event API.
A very brief documention of the API can be found at https://radar.squat.net/en/api
This document will give a more detailed description and provide examples for both the web api and the go bindings found in this package.
General ¶
The radar database consists of the following entities:
- events : any kind of event, e.g. a party, workshop, etc.
- groups : a group organizes events. Some groups just act as promoters and add events to the database without actually organzing them, e.g. "Stressfaktor". An event can be linked to multiple groups.
- location : a place where an event happens.
- taxonomy term : a category for events, groups and locations, e.g. "party", "workshop", "bar/cafe", etc. Any of the above entities can be linked to multiple taxonomy terms.
Each entity comes with a set of fields. The list of available fields for each entity can be found in the corresponding subpackages (see subdirectories). All entities have a common field UUID which uniquely identifies an entity instance.
Endpoints ¶
The rest API provides endpoints for each of those entities:
event: https://radar.squat.net/api/1.2/node/[uuid].json file: https://radar.squat.net/api/1.2/file/[uuid].json group: https://radar.squat.net/api/1.2/node/[uuid].json location: https://radar.squat.net/api/1.2/location/[uuid].json term: https://radar.squat.net/api/1.2/taxonomy_term/[uuid].json
Entity parameters ¶
The entity endpoints support two parameters:
- fields: the fields to be returned.
- language: use the specified language, if available.
By default, all available fields for an entity are returned. Alternatively, a comma-separated list of fields can be passed:
https://radar.squat.net/api/1.2/node/[uuid].json?fields=field1,field2,field3
The default language is english (or UND???). To change the language pass an ISO language code like this:
https://radar.squat.net/api/1.2/node/[uuid].json?language=de
The corresponding go bindings for these endpoints provided by this package are named Event(), Group(), Location() and Term() and can be found below.
Search Endpoints ¶
The API supports searching the database for entities through the following endpoints:
event: https://radar.squat.net/api/1.2/search/events.json group: https://radar.squat.net/api/1.2/search/groups.json location: https://radar.squat.net/api/1.2/search/location.json term: https://radar.squat.net/api/1.2/search/term.json
Without any parameters, events will return all events with an end time greater than (now - 2h). group, location and term will simply return all.
In most cases you'd only want a subset of the data, therefore the API provides different means of filtering the results. See Facet and Filter below for info and examples on how to filter the results.
Apart from facets and filters, the search API supports the following other parameters:
- keys: string used for full-text search.
- fields: see Entity Parameters above, with the extension that reference fields can be auto resolved (see ResolveField below).
- language: see Entity Parameters above.
- limit: return at most n results, see Limit() below.
- sort: sorts the results by the specified field in the given order (asc or desc), see Sort() below.
Searching with this library is done via the SearchBuilder type (see below for a description and examples).
Index ¶
- Constants
- func ResolveField(reference string, target string, targetN ...string) string
- type Facet
- type Filter
- type RadarClient
- func (radar *RadarClient) Event(uuid string, language *lang.Tag, fields ...string) (*event.Event, error)
- func (radar *RadarClient) File(uuid string, language *lang.Tag, fields ...string) (*file.File, error)
- func (radar *RadarClient) Group(uuid string, language *lang.Tag, fields ...string) (*group.Group, error)
- func (radar *RadarClient) Location(uuid string, language *lang.Tag, fields ...string) (*location.Location, error)
- func (radar *RadarClient) SearchEvents(sb *SearchBuilder) (*SearchResultEvents, error)
- func (radar *RadarClient) SearchGroup(sb *SearchBuilder) (*SearchResultGroups, error)
- func (radar *RadarClient) SearchLocation(sb *SearchBuilder) (*SearchResultLocations, error)
- func (radar *RadarClient) SearchTerm(sb *SearchBuilder) (*SearchResultTerms, error)
- func (radar *RadarClient) Term(uuid string, language *lang.Tag, fields ...string) (*term.Term, error)
- type ResultFacet
- type SearchBuilder
- func (sb *SearchBuilder) Facets(facets ...Facet)
- func (sb *SearchBuilder) Fields(fields ...string)
- func (sb *SearchBuilder) Filters(filters ...Filter)
- func (sb *SearchBuilder) Key(key string)
- func (sb *SearchBuilder) Language(language lang.Tag)
- func (sb *SearchBuilder) Limit(limit uint16)
- func (sb *SearchBuilder) Sort(field string, descending bool)
- type SearchResultEvents
- type SearchResultGroups
- type SearchResultLocations
- type SearchResultTerms
Examples ¶
Constants ¶
const ( OperatorAnd = "~and" OperatorOR = "~or" ComparatorEQ = "~e" ComparatorNEQ = "~ne" ComparatorGT = "~gt" ComparatorGTE = "~gte" ComparatorLT = "~lt" ComparatorLTE = "~lte" )
const ( // Start date and time of an event, unix timestamp FilterEventStartDateTime = "search_api_aggregation_1" // End date and time of an event, unix timestamp FilterEventEndDateTime = "search_api_aggregation_3" // City an event is taking place at. FilterEventLocation = "field_offline:field_address:locality" )
Variables ¶
This section is empty.
Functions ¶
func ResolveField ¶
When searching for an entity, the result may contain a field which is a reference to another entity. Normally, one would have to do another API call to fetch this referenced entity. The radar api, however, allows us to specify fields which should be resolved automatically.
In the radar rest api this is done like this
fields=referenceField:targetField
or even
fields=referenceField:anotherReference:targetField
The Go equivalent is using this method
ResolveField(referenceField, targetField)
or
ResolveField(referenceField, anotherReference, targetField)
The arguments can be any of the event/group/location/term FieldXXXs
Example ¶
Search result for events showing the title and the field 'offline', which is a reference to the location entity.
Using the radar rest api
https://radar.squat.net/api/1.2/search/events.json?fields=title,offline
In Go
radar := NewRadarClient() sb := NewSearch(typeEvent) sb.Fields(event.FieldTitle, event.FieldOffline) raw, err := radar.Search(sb)
Result
"346823": { "offline": [ { "uri": "https://radar.squat.net/api/1.2/location/8b8b63b2-64e5-4831-a91d-7f77bb510890", "id": "8b8b63b2-64e5-4831-a91d-7f77bb510890", "resource": "location", "title": "K19 Café Kreutzigerstr. 19 Berlin Deutschland" } ], "title": "CryptoParty" }
Clicking the uri will reveal the following structure of the location entity:
{ "address": { "country": "DE", "name_line": "K19 Café", "first_name": "K19", "last_name": "Café", "organisation_name": null, "administrative_area": null, "sub_administrative_area": null, "locality": "Berlin", "dependent_locality": null, "postal_code": "10247", "thoroughfare": "Kreutzigerstr. 19", "premise": "" }, "directions": "U-Bhf. Samariterstrasse", "map": { "geom": "POINT (13.4600646 52.5131015)", "geo_type": "point", "lat": "52.513101500000", "lon": "13.460064600000", "left": "13.460064600000", "top": "52.513101500000", "right": "13.460064600000", "bottom": "52.513101500000", "srid": null, "latlon": "52.513101500000,13.460064600000", "schemaorg_shape": "" }, "timezone": "Europe/Berlin", "squat": null, "id": "225", "type": "location", "title": "K19 Café Kreutzigerstr. 19 Berlin Deutschland", "uuid": "8b8b63b2-64e5-4831-a91d-7f77bb510890", "feed_nid": null }
We can now resolve the address Field (or any of the others) like this
https://radar.squat.net/api/1.2/search/events.json?fields=title,offline,offline:address
In Go
radar := NewRadarClient() sb := NewSearch(typeEvent) sb.Fields(event.FieldTitle, event.FieldOffline, ResolveField(event.Offline, location.Address)) raw, err := radar.Search(sb)
Result
"346823": { "offline": [ { "uri": "https://radar.squat.net/api/1.2/location/8b8b63b2-64e5-4831-a91d-7f77bb510890", "id": "8b8b63b2-64e5-4831-a91d-7f77bb510890", "resource": "location", "title": "K19 Café Kreutzigerstr. 19 Berlin Deutschland", "address": { "country": "DE", "name_line": "K19 Café", "first_name": "K19", "last_name": "Café", "organisation_name": null, "administrative_area": null, "sub_administrative_area": null, "locality": "Berlin", "dependent_locality": null, "postal_code": "10247", "thoroughfare": "Kreutzigerstr. 19", "premise": "" } } ], "title": "CryptoParty" }
Example ¶
Get all events in Berlin and include the address field of the locations.
// https://radar.squat.net/api/1.2/search/events.json?facets[city][]=Berlin&fields=title,offline,offline:address radar := NewRadarClient() sb := &SearchBuilder{} sb.Facets(Facet{event.FacetCity, "Berlin"}) sb.Fields(event.FieldTitle, event.FieldOffline, ResolveField(event.FieldOffline, location.FieldAddress)) result, err := radar.SearchEvents(sb) if err != nil { fmt.Printf("%v", err) return } if result == nil { fmt.Println("No results") } fmt.Printf("%v", result)
Output:
Types ¶
type Facet ¶
type Facet struct { // One of event/group/location/term FacetXXXs. Must match the entity you are searching for, // e.g. when searching for an Event it must be from event.FacetXXXX Key string Value string }
Facets provide an easy way to filter results by entity properties.
For each entity there's a predefined set of facets. The list of available facets can be found in the corresponding subpackages (see subdirectories).
Facets can be passed to the server by using the facets parameter:
https://radar.squat.net/api/1.2/search/events.json?facets[facet][]=value
Example
https://radar.squat.net/api/1.2/search/events.json?facets[city][]=Berlin
Multiple facets can be passed, even the same with different values. When passing the same facet with different values the logical operation (AND, OR) depends on the actual facet. Each facet is annotated with its operator (see Constants in the corresponding subpackages)
Example
category operator is AND, this call returns events which have both the bar/cafe AND theater category https://radar.squat.net/api/1.2/search/events.json?facets[category][]=bar-cafe&facets[category][]=theater group operator is OR, this call returns events organized by group 339006 OR 1599 https://radar.squat.net/api/1.2/search/events.json?facets[group][]=339006&fields=*&facets[group][]=1599
Example ¶
Get all events in Berlin with the category work-space/diy happening on the 2020-11-24
radar := NewRadarClient() sb := &SearchBuilder{} sb.Facets( Facet{event.FacetCity, "Berlin"}, Facet{event.FacetCategory, "work-space-diy"}, Facet{event.FacetDate, "2020-11-24"}) result, err := radar.SearchEvents(sb) if err != nil { fmt.Printf("%v", err) return } if result == nil { fmt.Println("No results") } fmt.Printf("%v", result)
Output:
type Filter ¶
type Filter interface{}
Filters provide a somewhat more complex way to filter results.
Note: filtering only works on indexed fields.
Filters can be passed to the server by using the filter parameter:
https://radar.squat.net/api/1.2/search/events.json?filter[~operator][field][~comparator]=value
Possible operators are
- ~and: all filters with ~and must evaluate to true
- ~or: at least one of the ~or filters must evaluate to true
Comparators:
- ~e: equals
- ~ne: not equal
- ~gt: greater than
- ~gte: greater or equal than
- ~lt: less than
- ~lte: less or equal than
Note: filtering also works on resolved fields (see ResolveField).
Example
Get all events in Berlin https://radar.squat.net/api/1.2/search/events.json?filter[~and][field_offline:field_address:locality][~eq]=Berlin
Note: most of the equal filters, like in this example, can be be done with Facets in a simpler manner (see Facets).
One of the more interesting things you can do is filtering for a time period
Get all events in Berlin with a start date between 2020-11-03 00:00:00 and 2020-11-25 00:00:00 https://radar.squat.net/api/1.2/search/events.json?facets[city][]=Berlin&filter[~and][search_api_aggregation_1][~gt]=1604358000&filter[~or][search_api_aggregation_1][~lt]=1606258800
In Go filters can be created with CreateFilter() and CreateRangeFilter().
There are some predefined constants which can be used as fields when filtering (FilterXXX), see constants above.
Limitations ¶
Filters can't be grouped, i.e. things like
(cond1 AND cond2) OR cond3
are not possible.
A field can't be used in more than one equals filter, i.e. you can't filter for events in Berlin OR Amsterdam because that would require using the field locality twice.
filter[~and][field_offline:field_address:locality][~eq]=Berlin&filter[~or][field_offline:field_address:locality][~eq]=Amsterdam
func CreateFilter ¶
Creates a filter which can be passed to SearchBuilder.Filters().
See type Filter for a detailed description.
Example ¶
Get all events in Berlin which are not organized/promoted by group "Stressfaktor" (id: 1599)
// https://radar.squat.net/api/1.2/search/events.json?facets[city][]=Berlin&filter[~and][og_group_ref][~ne]=1599 radar := NewRadarClient() sb := &SearchBuilder{} sb.Facets(Facet{event.FacetCity, "Berlin"}) sb.Filters(CreateFilter(OperatorAnd, event.FieldOgGroupRef, ComparatorNEQ, "1599")) result, err := radar.SearchEvents(sb) if err != nil { fmt.Printf("%v", err) return } if result == nil { fmt.Println("No results") } fmt.Printf("%v", result)
Output:
func CreaterRangeFilter ¶
Creates a range filter which can be passed to SearchBuilder.Filters().
See type Filter for a detailed description.
Example ¶
Get all events in Berlin with a start date between 2020-11-03 00:00:00 and 2020-11-25 00:00:00
// https://radar.squat.net/api/1.2/search/events.json?facets[city][]=Berlin&filter[~and][search_api_aggregation_1][~gt]=1604358000&filter[~or][search_api_aggregation_1][~lt]=1606258800 radar := NewRadarClient() sb := &SearchBuilder{} sb.Facets(Facet{event.FacetCity, "Berlin"}) sb.Filters(CreaterRangeFilter(FilterEventStartDateTime, "1604358000", "1606258800")) result, err := radar.SearchEvents(sb) if err != nil { fmt.Printf("%v", err) return } if result == nil { fmt.Println("No results") } fmt.Printf("%v", result)
Output:
type RadarClient ¶
type RadarClient struct {
// contains filtered or unexported fields
}
func NewRadarClient ¶
func NewRadarClient() *RadarClient
Returns an instance of RadarClient which can be used to interact with the radar server.
func (*RadarClient) Event ¶
func (radar *RadarClient) Event(uuid string, language *lang.Tag, fields ...string) (*event.Event, error)
Get the Event associated with uuid. If no fields are specified the default are returned.
Example ¶
Get event "e81b15f9-663f-4270-b94b-269176cd9f3f".
// https://radar.squat.net/api/1.2/node/e81b15f9-663f-4270-b94b-269176cd9f3f.json radar := NewRadarClient() result, err := radar.Event("e81b15f9-663f-4270-b94b-269176cd9f3f", nil) if err != nil { fmt.Printf("error: %v", err) return } fmt.Printf("%v", result.Title)
Output: Seawatch Soli Fete Tag 1
Example (Fields) ¶
Get event "e81b15f9-663f-4270-b94b-269176cd9f3f" with fields title and event status.
// https://radar.squat.net/api/1.2/node/e81b15f9-663f-4270-b94b-269176cd9f3f.json?fields=title,event_status radar := NewRadarClient() result, err := radar.Event("e81b15f9-663f-4270-b94b-269176cd9f3f", nil, event.FieldTitle, event.FieldEventStatus) if err != nil { fmt.Printf("error: %v", err) return } fmt.Printf("title: %s, status: %s", result.Title, result.EventStatus)
Output: title: Seawatch Soli Fete Tag 1, status: confirmed
func (*RadarClient) File ¶
func (radar *RadarClient) File(uuid string, language *lang.Tag, fields ...string) (*file.File, error)
Get the File associated with uuid. If no fields are specified the default are returned.
func (*RadarClient) Group ¶
func (radar *RadarClient) Group(uuid string, language *lang.Tag, fields ...string) (*group.Group, error)
Get the Group associated with uuid. If no fields are specified the default are returned.
Example ¶
Get group "Liebig34" : "7a8de6aa-5951-467f-a4a4-1d558eea5d3c" and print title and description.
// https://radar.squat.net/api/1.2/node/7a8de6aa-5951-467f-a4a4-1d558eea5d3c.json radar := NewRadarClient() result, err := radar.Group("7a8de6aa-5951-467f-a4a4-1d558eea5d3c", nil) if err != nil { fmt.Printf("error: %v", err) return } fmt.Printf("title: %s, description: %s", result.Title, result.Body.Value)
Output: title: Liebig34, description: <p>Anarcha-Queer-Feminist houseproject in Berlin-Friedrichshain.</p> <p>Non-smoking bar.</p> <p> </p>
func (*RadarClient) Location ¶
func (radar *RadarClient) Location(uuid string, language *lang.Tag, fields ...string) (*location.Location, error)
Get the Location associated with uuid. If no fields are specified the default are returned.
Example ¶
Get location "2130ff33-8af2-4c76-a693-75d3b978a2aa" and print name and street.
// https://radar.squat.net/api/1.2/location/2130ff33-8af2-4c76-a693-75d3b978a2aa.json radar := NewRadarClient() result, err := radar.Location("2130ff33-8af2-4c76-a693-75d3b978a2aa", nil) if err != nil { fmt.Printf("error: %v", err) return } fmt.Printf("name: %s, street: %s", result.Address.NameLine, result.Address.Thoroughfare)
Output: name: Mensch Meier, street: Storkower Str. 121
func (*RadarClient) SearchEvents ¶
func (radar *RadarClient) SearchEvents(sb *SearchBuilder) (*SearchResultEvents, error)
Search the radar database for Events. Returns nil if no results were found.
func (*RadarClient) SearchGroup ¶
func (radar *RadarClient) SearchGroup(sb *SearchBuilder) (*SearchResultGroups, error)
Search the radar database for Groups. Returns nil if no results were found.
func (*RadarClient) SearchLocation ¶
func (radar *RadarClient) SearchLocation(sb *SearchBuilder) (*SearchResultLocations, error)
Search the radar database for Locations. Returns nil if no results were found.
Note: By default, no fields are returned for the locations. Use SearchBuilder.Fields() to get a meaningful response.
func (*RadarClient) SearchTerm ¶
func (radar *RadarClient) SearchTerm(sb *SearchBuilder) (*SearchResultTerms, error)
Search the radar database for Terms. Returns nil if no result were found.
func (*RadarClient) Term ¶
func (radar *RadarClient) Term(uuid string, language *lang.Tag, fields ...string) (*term.Term, error)
Get the Term associated with uuid. If no fields are specified the default are returned.
Example ¶
Get taxonomy term "2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8" and print name and description.
// https://radar.squat.net/api/1.2/taxonomy_term/2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8.json radar := NewRadarClient() result, err := radar.Term("2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8", nil) if err != nil { fmt.Printf("error: %v", err) return } fmt.Printf("name: %s, description: %s", result.Name, result.Description)
Output: name: bar/cafe, description: <p>somewhere were you can go for a drink and to meet people</p>
Example (Spanish) ¶
Get taxonomy term "2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8" and print name and description in spanish.
// https://radar.squat.net/api/1.2/taxonomy_term/2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8.json?language=es radar := NewRadarClient() result, err := radar.Term("2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8", &language.Spanish) if err != nil { fmt.Printf("error: %v", err) return } fmt.Printf("name: %s, description: %s", result.Name, result.Description)
Output: name: bar/café, description: <p>para tomarse una copita, conocer gente maja...</p>
type ResultFacet ¶
type ResultFacet struct { Filter string `json:"filter"` Count int64 `json:"count"` Formatted string `json:"formatted"` }
The response to a search request will return a list of available facets.
func (*ResultFacet) UnmarshalJSON ¶
func (e *ResultFacet) UnmarshalJSON(data []byte) error
type SearchBuilder ¶
type SearchBuilder struct {
// contains filtered or unexported fields
}
A SearchBuilder is used to create a search request which can be passed to RadarClient.Search().
The zero value is ready to use.
func (*SearchBuilder) Facets ¶
func (sb *SearchBuilder) Facets(facets ...Facet)
Sets the facets which will be used to filter the results. See Facet above.
func (*SearchBuilder) Fields ¶
func (sb *SearchBuilder) Fields(fields ...string)
Sets the fields which will be returned for each result.
Fields must come from the entity you are searching for, e.g. for Event event.FieldXXXX. See subpackages for the available fields for each entity.
func (*SearchBuilder) Filters ¶
func (sb *SearchBuilder) Filters(filters ...Filter)
Sets the filters which will be used to filter the results. See Filter above.
func (*SearchBuilder) Key ¶
func (sb *SearchBuilder) Key(key string)
Sets a key for full-text search.
func (*SearchBuilder) Language ¶
func (sb *SearchBuilder) Language(language lang.Tag)
Sets the language for the response.
func (*SearchBuilder) Limit ¶
func (sb *SearchBuilder) Limit(limit uint16)
Sets the amount of results returned.
Must be 0 <= limit <= 500
func (*SearchBuilder) Sort ¶
func (sb *SearchBuilder) Sort(field string, descending bool)
Sets the field used to sort the results.
Only works for indexed fields.