Skip to content

Commit 68082e4

Browse files
wwwdatasharpner
authored andcommitted
Add easy way to combine multiple API versions
It was previously already possible by taking the router instance of the first API and passing it into the second. Now there is a convenience method for this.
1 parent 8bf46b9 commit 68082e4

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

api_public.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ func (api *API) UseMiddleware(middleware ...HandlerFunc) {
5252
api.middlewares = append(api.middlewares, middleware...)
5353
}
5454

55+
// NewAPIVersion can be used to chain an additional API version to the routing of a previous
56+
// one. Use this if you have multiple version prefixes and want to combine all
57+
// your different API versions. This reuses the baseURL or URLResolver
58+
func (api *API) NewAPIVersion(prefix string) *API {
59+
return newAPI(prefix, api.info.resolver, api.router)
60+
}
61+
5562
// NewAPIWithResolver can be used to create an API with a custom URL resolver.
5663
func NewAPIWithResolver(prefix string, resolver URLResolver) *API {
5764
handler := notAllowedHandler{}

api_test.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,4 +1758,141 @@ var _ = Describe("RestHandler", func() {
17581758
Expect(error.Errors).To(ContainElement(expectedError("pink", "users")))
17591759
})
17601760
})
1761+
1762+
Context("Works with multiple API verisons", func() {
1763+
var (
1764+
source, source2 *fixtureSource
1765+
mainAPI, apiV2 *API
1766+
rec *httptest.ResponseRecorder
1767+
)
1768+
1769+
BeforeEach(func() {
1770+
author := User{ID: "666", Name: "Tester", Info: "Is curious about testing"}
1771+
source = &fixtureSource{map[string]*Post{
1772+
"1": {ID: "1", Title: "Nice Post", Value: null.FloatFrom(13.37), Author: &author},
1773+
}, false}
1774+
mainAPI = NewAPI("v1")
1775+
mainAPI.AddResource(Post{}, source)
1776+
1777+
author2 := User{ID: "888", Name: "Version 2 Tester", Info: "Is the next version"}
1778+
source2 = &fixtureSource{map[string]*Post{
1779+
"1": {ID: "1", Title: "Even better post", Value: null.FloatFrom(13.37), Author: &author2},
1780+
}, false}
1781+
apiV2 = mainAPI.NewAPIVersion("v2")
1782+
apiV2.AddResource(Post{}, source2)
1783+
rec = httptest.NewRecorder()
1784+
})
1785+
1786+
It("Works for v1", func() {
1787+
req, err := http.NewRequest("GET", "/v1/posts", nil)
1788+
Expect(err).ToNot(HaveOccurred())
1789+
mainAPI.Handler().ServeHTTP(rec, req)
1790+
Expect(rec.Code).To(Equal(http.StatusOK))
1791+
Expect(rec.Body.Bytes()).To(MatchJSON(`
1792+
{
1793+
"data": [
1794+
{
1795+
"type": "posts",
1796+
"id": "1",
1797+
"attributes": {
1798+
"title": "Nice Post",
1799+
"value": 13.37
1800+
},
1801+
"relationships": {
1802+
"author": {
1803+
"links": {
1804+
"related": "/v1/posts/1/author",
1805+
"self": "/v1/posts/1/relationships/author"
1806+
},
1807+
"data": {
1808+
"type": "users",
1809+
"id": "666"
1810+
}
1811+
},
1812+
"bananas": {
1813+
"links": {
1814+
"related": "/v1/posts/1/bananas",
1815+
"self": "/v1/posts/1/relationships/bananas"
1816+
},
1817+
"data": []
1818+
},
1819+
"comments": {
1820+
"links": {
1821+
"related": "/v1/posts/1/comments",
1822+
"self": "/v1/posts/1/relationships/comments"
1823+
},
1824+
"data": []
1825+
}
1826+
}
1827+
}
1828+
],
1829+
"included": [
1830+
{
1831+
"type": "users",
1832+
"id": "666",
1833+
"attributes": {
1834+
"name": "Tester",
1835+
"info": "Is curious about testing"
1836+
}
1837+
}
1838+
]
1839+
}`))
1840+
})
1841+
1842+
It("Works for v2", func() {
1843+
req, err := http.NewRequest("GET", "/v2/posts", nil)
1844+
Expect(err).ToNot(HaveOccurred())
1845+
mainAPI.Handler().ServeHTTP(rec, req)
1846+
Expect(rec.Code).To(Equal(http.StatusOK))
1847+
Expect(rec.Body.Bytes()).To(MatchJSON(`
1848+
{
1849+
"data": [
1850+
{
1851+
"type": "posts",
1852+
"id": "1",
1853+
"attributes": {
1854+
"title": "Even better post",
1855+
"value": 13.37
1856+
},
1857+
"relationships": {
1858+
"author": {
1859+
"links": {
1860+
"related": "/v2/posts/1/author",
1861+
"self": "/v2/posts/1/relationships/author"
1862+
},
1863+
"data": {
1864+
"type": "users",
1865+
"id": "888"
1866+
}
1867+
},
1868+
"bananas": {
1869+
"links": {
1870+
"related": "/v2/posts/1/bananas",
1871+
"self": "/v2/posts/1/relationships/bananas"
1872+
},
1873+
"data": []
1874+
},
1875+
"comments": {
1876+
"links": {
1877+
"related": "/v2/posts/1/comments",
1878+
"self": "/v2/posts/1/relationships/comments"
1879+
},
1880+
"data": []
1881+
}
1882+
}
1883+
}
1884+
],
1885+
"included": [
1886+
{
1887+
"type": "users",
1888+
"id": "888",
1889+
"attributes": {
1890+
"name": "Version 2 Tester",
1891+
"info": "Is the next version"
1892+
}
1893+
}
1894+
]
1895+
}`))
1896+
})
1897+
})
17611898
})

0 commit comments

Comments
 (0)